1 /*****
2 *
3 * Copyright (C) 2003-2015 CS-SI. All Rights Reserved.
4 * Author: Nicolas Delon <nicolas.delon@prelude-ids.com>
5 *
6 * This file is part of the Prelude library.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 *****/
23 
24 #include "libmissing.h"
25 
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <sys/types.h>
30 
31 #include "prelude-error.h"
32 #include "prelude-inttypes.h"
33 #include "prelude-string.h"
34 #include "common.h"
35 #include "idmef-data.h"
36 
37 
38 /*
39  * Data structure may be free'd
40  */
41 #define IDMEF_DATA_OWN_STRUCTURE  0x1
42 
43 /*
44  * Data content may be free'd
45  */
46 #define IDMEF_DATA_OWN_DATA       0x2
47 
48 
49 #define IDMEF_DATA_DECL(idmef_data_type, c_type, name, fname)         \
50 int idmef_data_new_ ## name(idmef_data_t **nd, c_type val)            \
51 {                                                                     \
52         int ret;                                                      \
53                                                                       \
54         ret = idmef_data_new(nd);                                     \
55         if ( ret < 0 )                                                \
56                 return ret;                                           \
57                                                                       \
58         idmef_data_set_ ## fname(*nd, val);                           \
59                                                                       \
60         return ret;                                                   \
61 }                                                                     \
62                                                                       \
63 void idmef_data_set_ ## name(idmef_data_t *ptr, c_type val)           \
64 {                                                                     \
65         prelude_return_if_fail(ptr);                                  \
66         idmef_data_destroy_internal(ptr);                             \
67         ptr->type = idmef_data_type;                                  \
68         ptr->len = sizeof(val);                                       \
69         ptr->data.fname ## _data = val;                               \
70 }                                                                     \
71                                                                       \
72 c_type idmef_data_get_ ## name(const idmef_data_t *ptr)               \
73 {                                                                     \
74         return ptr->data.fname ## _data;                              \
75 }
76 
77 
IDMEF_DATA_DECL(IDMEF_DATA_TYPE_CHAR,char,char,char)78 IDMEF_DATA_DECL(IDMEF_DATA_TYPE_CHAR, char, char, char)
79 IDMEF_DATA_DECL(IDMEF_DATA_TYPE_BYTE, uint8_t, byte, byte)
80 IDMEF_DATA_DECL(IDMEF_DATA_TYPE_INT, uint32_t, uint32, int)
81 IDMEF_DATA_DECL(IDMEF_DATA_TYPE_INT, uint64_t, uint64, int)
82 IDMEF_DATA_DECL(IDMEF_DATA_TYPE_INT, int64_t, int, int)
83 IDMEF_DATA_DECL(IDMEF_DATA_TYPE_FLOAT, float, float, float)
84 
85 
86 int idmef_data_new(idmef_data_t **data)
87 {
88         *data = calloc(1, sizeof(**data));
89         if ( ! *data )
90                 return prelude_error_from_errno(errno);
91 
92         (*data)->refcount = 1;
93         (*data)->flags |= IDMEF_DATA_OWN_STRUCTURE;
94 
95         return 0;
96 }
97 
98 
idmef_data_new_time(idmef_data_t ** data,idmef_time_t * time)99 int idmef_data_new_time(idmef_data_t **data, idmef_time_t *time)
100 {
101         int ret;
102 
103         ret = idmef_data_new(data);
104         if ( ret < 0 )
105                 return ret;
106 
107         (*data)->len = 1;
108         (*data)->type = IDMEF_DATA_TYPE_TIME;
109         (*data)->flags |= IDMEF_DATA_OWN_DATA;
110         (*data)->data.ro_data = time;
111 
112         return 0;
113 }
114 
115 
idmef_data_set_time(idmef_data_t * data,idmef_time_t * time)116 void idmef_data_set_time(idmef_data_t *data, idmef_time_t *time)
117 {
118         data->len = 1;
119         data->type = IDMEF_DATA_TYPE_TIME;
120         data->flags |= IDMEF_DATA_OWN_DATA;
121         data->data.ro_data = time;
122 }
123 
idmef_data_ref(idmef_data_t * data)124 idmef_data_t *idmef_data_ref(idmef_data_t *data)
125 {
126         prelude_return_val_if_fail(data, NULL);
127 
128         data->refcount++;
129         return data;
130 }
131 
132 
133 
idmef_data_set_ptr_ref_fast(idmef_data_t * data,idmef_data_type_t type,const void * ptr,size_t len)134 int idmef_data_set_ptr_ref_fast(idmef_data_t *data, idmef_data_type_t type, const void *ptr, size_t len)
135 {
136         prelude_return_val_if_fail(data, prelude_error(PRELUDE_ERROR_ASSERTION));
137         prelude_return_val_if_fail(ptr, prelude_error(PRELUDE_ERROR_ASSERTION));
138 
139         idmef_data_destroy_internal(data);
140 
141         data->type = type;
142         data->data.ro_data = ptr;
143         data->len = len;
144 
145         return 0;
146 }
147 
148 
149 
idmef_data_set_ptr_dup_fast(idmef_data_t * data,idmef_data_type_t type,const void * ptr,size_t len)150 int idmef_data_set_ptr_dup_fast(idmef_data_t *data, idmef_data_type_t type, const void *ptr, size_t len)
151 {
152         void *new;
153 
154         prelude_return_val_if_fail(data, prelude_error(PRELUDE_ERROR_ASSERTION));
155         prelude_return_val_if_fail(ptr, prelude_error(PRELUDE_ERROR_ASSERTION));
156 
157         idmef_data_destroy_internal(data);
158 
159         new = malloc(len);
160         if ( ! new )
161                 return -1;
162 
163         memcpy(new, ptr, len);
164 
165         data->type = type;
166         data->data.rw_data = new;
167         data->len = len;
168         data->flags |= IDMEF_DATA_OWN_DATA;
169 
170         return 0;
171 }
172 
173 
174 
idmef_data_set_ptr_nodup_fast(idmef_data_t * data,idmef_data_type_t type,void * ptr,size_t len)175 int idmef_data_set_ptr_nodup_fast(idmef_data_t *data, idmef_data_type_t type, void *ptr, size_t len)
176 {
177         prelude_return_val_if_fail(data, prelude_error(PRELUDE_ERROR_ASSERTION));
178         prelude_return_val_if_fail(ptr, prelude_error(PRELUDE_ERROR_ASSERTION));
179 
180         idmef_data_destroy_internal(data);
181 
182         data->type = type;
183         data->data.rw_data= ptr;
184         data->len = len;
185         data->flags |= IDMEF_DATA_OWN_DATA;
186 
187         return 0;
188 }
189 
190 
191 
idmef_data_new_ptr_ref_fast(idmef_data_t ** data,idmef_data_type_t type,const void * ptr,size_t len)192 int idmef_data_new_ptr_ref_fast(idmef_data_t **data, idmef_data_type_t type, const void *ptr, size_t len)
193 {
194         int ret;
195 
196         ret = idmef_data_new(data);
197         if ( ret < 0 )
198                 return ret;
199 
200         ret = idmef_data_set_ptr_ref_fast(*data, type, ptr, len);
201         if ( ret < 0 )
202                 idmef_data_destroy(*data);
203 
204         return ret;
205 }
206 
207 
208 
idmef_data_new_ptr_dup_fast(idmef_data_t ** data,idmef_data_type_t type,const void * ptr,size_t len)209 int idmef_data_new_ptr_dup_fast(idmef_data_t **data, idmef_data_type_t type, const void *ptr, size_t len)
210 {
211         int ret;
212 
213         ret = idmef_data_new(data);
214         if ( ret < 0 )
215                 return ret;
216 
217         ret = idmef_data_set_ptr_dup_fast(*data, type, ptr, len);
218         if ( ret < 0 )
219                 idmef_data_destroy(*data);
220 
221         return ret;
222 }
223 
224 
225 
idmef_data_new_ptr_nodup_fast(idmef_data_t ** data,idmef_data_type_t type,void * ptr,size_t len)226 int idmef_data_new_ptr_nodup_fast(idmef_data_t **data, idmef_data_type_t type, void *ptr, size_t len)
227 {
228         int ret;
229 
230         ret = idmef_data_new(data);
231         if ( ret < 0 )
232                 return ret;
233 
234         ret = idmef_data_set_ptr_nodup_fast(*data, type, ptr, len);
235         if ( ret < 0 )
236                 idmef_data_destroy(*data);
237 
238         return ret;
239 }
240 
241 
242 
243 
244 /**
245  * idmef_data_copy_ref:
246  * @src: Source #idmef_data_t object.
247  * @dst: Destination #idmef_data_t object.
248  *
249  * Makes @dst reference the same buffer as @src.
250  *
251  * Returns: 0 on success, a negative value if an error occured.
252  */
idmef_data_copy_ref(const idmef_data_t * src,idmef_data_t * dst)253 int idmef_data_copy_ref(const idmef_data_t *src, idmef_data_t *dst)
254 {
255         prelude_return_val_if_fail(src, prelude_error(PRELUDE_ERROR_ASSERTION));
256         prelude_return_val_if_fail(dst, prelude_error(PRELUDE_ERROR_ASSERTION));
257 
258         idmef_data_destroy_internal(dst);
259 
260         dst->type = src->type;
261         dst->len = src->len;
262         dst->data = src->data;
263         dst->flags &= ~IDMEF_DATA_OWN_DATA;
264 
265         return 0;
266 }
267 
268 
269 
270 
271 /**
272  * idmef_data_copy_dup:
273  * @src: Source #idmef_data_t object.
274  * @dst: Destination #idmef_data_t object.
275  *
276  * Copies @src to @dst, including the associated buffer.
277  * This is an alternative to idmef_data_clone().
278  *
279  * Returns: 0 on success, a negative value if an error occured.
280  */
idmef_data_copy_dup(const idmef_data_t * src,idmef_data_t * dst)281 int idmef_data_copy_dup(const idmef_data_t *src, idmef_data_t *dst)
282 {
283         int ret;
284 
285         prelude_return_val_if_fail(src, prelude_error(PRELUDE_ERROR_ASSERTION));
286         prelude_return_val_if_fail(dst, prelude_error(PRELUDE_ERROR_ASSERTION));
287 
288         idmef_data_destroy_internal(dst);
289 
290         dst->type = src->type;
291         dst->flags |= IDMEF_DATA_OWN_DATA;
292         dst->len = src->len;
293 
294         if ( src->type == IDMEF_DATA_TYPE_TIME ) {
295                 ret = idmef_time_clone((idmef_time_t *) src->data.rw_data, (idmef_time_t **) &dst->data.rw_data);
296                 if ( ret < 0 )
297                         return ret;
298         }
299 
300         else if ( src->type == IDMEF_DATA_TYPE_CHAR_STRING || src->type == IDMEF_DATA_TYPE_BYTE_STRING ) {
301                 dst->data.rw_data = malloc(src->len);
302                 if ( ! dst->data.rw_data )
303                         return -1;
304 
305                 memcpy(dst->data.rw_data, src->data.ro_data, src->len);
306         } else {
307                 dst->data = src->data;
308         }
309 
310         return 0;
311 }
312 
313 
314 
idmef_data_clone(const idmef_data_t * src,idmef_data_t ** dst)315 int idmef_data_clone(const idmef_data_t *src, idmef_data_t **dst)
316 {
317         int ret;
318 
319         prelude_return_val_if_fail(src, prelude_error(PRELUDE_ERROR_ASSERTION));
320 
321         ret = idmef_data_new(dst);
322         if ( ret < 0 )
323                 return ret;
324 
325         ret = idmef_data_copy_dup(src, *dst);
326         if ( ret < 0 )
327                 idmef_data_destroy(*dst);
328 
329         return ret;
330 }
331 
332 
333 
idmef_data_get_char_string(const idmef_data_t * data)334 const char *idmef_data_get_char_string(const idmef_data_t *data)
335 {
336         prelude_return_val_if_fail(data, NULL);
337         return data->data.ro_data;
338 }
339 
340 
341 
idmef_data_get_byte_string(const idmef_data_t * data)342 const unsigned char *idmef_data_get_byte_string(const idmef_data_t *data)
343 {
344         prelude_return_val_if_fail(data, NULL);
345         return data->data.ro_data;
346 }
347 
348 
349 
350 /**
351  * idmef_data_get_type
352  * @data: Pointer to an #idmef_data_t object.
353  *
354  * Returns: the type of the embedded data.
355  */
idmef_data_get_type(const idmef_data_t * data)356 idmef_data_type_t idmef_data_get_type(const idmef_data_t *data)
357 {
358         prelude_return_val_if_fail(data, prelude_error(PRELUDE_ERROR_ASSERTION));
359         return data->type;
360 }
361 
362 
363 
364 
365 /**
366  * idmef_data_get_len:
367  * @data: Pointer to an #idmef_data_t object.
368  *
369  * Returns: the length of data contained within @data object.
370  */
idmef_data_get_len(const idmef_data_t * data)371 size_t idmef_data_get_len(const idmef_data_t *data)
372 {
373         prelude_return_val_if_fail(data, 0);
374         return data->len;
375 }
376 
377 
378 
379 
380 /**
381  * idmef_data_get_data:
382  * @data: Pointer to an #idmef_data_t object.
383  *
384  * Returns: the data contained within @data object.
385  */
idmef_data_get_data(const idmef_data_t * data)386 const void *idmef_data_get_data(const idmef_data_t *data)
387 {
388         prelude_return_val_if_fail(data, NULL);
389 
390         switch ( data->type ) {
391         case IDMEF_DATA_TYPE_UNKNOWN:
392                 return NULL;
393 
394         case IDMEF_DATA_TYPE_CHAR_STRING:
395         case IDMEF_DATA_TYPE_BYTE_STRING:
396         case IDMEF_DATA_TYPE_TIME:
397                 return data->data.ro_data;
398 
399         default:
400                 return &data->data;
401         }
402 
403         return NULL;
404 }
405 
406 
407 
408 /**
409  * idmef_data_is_empty:
410  * @data: Pointer to an #idmef_data_t object.
411  *
412  * Returns: TRUE if empty, FALSE otherwise.
413  */
idmef_data_is_empty(const idmef_data_t * data)414 prelude_bool_t idmef_data_is_empty(const idmef_data_t *data)
415 {
416         prelude_return_val_if_fail(data, TRUE);
417         return (data->len == 0) ? TRUE : FALSE;
418 }
419 
420 
421 
bytes_to_string(prelude_string_t * out,const unsigned char * src,size_t size)422 static int bytes_to_string(prelude_string_t *out, const unsigned char *src, size_t size)
423 {
424         char c;
425         int ret;
426         static const char b64tbl[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
427 
428         while ( size ) {
429                 ret = prelude_string_ncat(out, &b64tbl[(src[0] >> 2) & 0x3f], 1);
430                 if ( ret < 0 )
431                         return ret;
432 
433                 c = b64tbl[((src[0] << 4) + ((--size) ? src[1] >> 4 : 0)) & 0x3f];
434 
435                 ret = prelude_string_ncat(out, &c, 1);
436                 if ( ret < 0 )
437                         return ret;
438 
439                 c = (size) ? b64tbl[((src[1] << 2) + ((--size) ? src[2] >> 6 : 0)) & 0x3f] : '=';
440 
441                 ret = prelude_string_ncat(out, &c, 1);
442                 if ( ret < 0 )
443                         return ret;
444 
445                 c = (size && size--) ? b64tbl[src[2] & 0x3f] : '=';
446 
447                 ret = prelude_string_ncat(out, &c, 1);
448                 if ( ret < 0 )
449                         return ret;
450 
451                 src += 3;
452         }
453 
454         return 0;
455 }
456 
457 
458 
459 
460 /**
461  * idmef_data_to_string:
462  * @data: Pointer to an #idmef_data_t object.
463  * @out: Pointer to a #prelude_string_t to store the formated data into.
464  *
465  * Formats data contained within @data to be printable,
466  * and stores the result in the provided @out buffer.
467  *
468  * Returns: 0 on success, a negative value if an error occured.
469  */
idmef_data_to_string(const idmef_data_t * data,prelude_string_t * out)470 int idmef_data_to_string(const idmef_data_t *data, prelude_string_t *out)
471 {
472         int ret = 0;
473 
474         prelude_return_val_if_fail(data, prelude_error(PRELUDE_ERROR_ASSERTION));
475         prelude_return_val_if_fail(out, prelude_error(PRELUDE_ERROR_ASSERTION));
476 
477         switch ( data->type ) {
478         case IDMEF_DATA_TYPE_UNKNOWN:
479                 return 0;
480 
481         case IDMEF_DATA_TYPE_CHAR:
482                 ret = prelude_string_sprintf(out, "%c", data->data.char_data);
483                 break;
484 
485         case IDMEF_DATA_TYPE_BYTE:
486                 /*
487                  * %hh convertion specifier is not portable.
488                  */
489                 ret = prelude_string_sprintf(out, "%u", (unsigned int) data->data.byte_data);
490                 break;
491 
492         case IDMEF_DATA_TYPE_UINT32:
493         case IDMEF_DATA_TYPE_INT:
494                 ret = prelude_string_sprintf(out, "%" PRELUDE_PRId64, data->data.int_data);
495                 break;
496 
497         case IDMEF_DATA_TYPE_FLOAT:
498                 ret = prelude_string_sprintf(out, "%f", data->data.float_data);
499                 break;
500 
501         case IDMEF_DATA_TYPE_CHAR_STRING:
502                 ret = prelude_string_sprintf(out, "%s", (const char *) data->data.ro_data);
503                 break;
504 
505         case IDMEF_DATA_TYPE_BYTE_STRING:
506                 ret = bytes_to_string(out, data->data.ro_data, data->len);
507                 break;
508 
509         case IDMEF_DATA_TYPE_TIME:
510                 ret = idmef_time_to_string(data->data.ro_data, out);
511                 break;
512         }
513 
514         return ret;
515 }
516 
517 
518 
519 /*
520  *  This function cannot be declared static because it is invoked
521  *  from idmef-tree-wrap.c
522  */
idmef_data_destroy_internal(idmef_data_t * ptr)523 void idmef_data_destroy_internal(idmef_data_t *ptr)
524 {
525         prelude_return_if_fail(ptr);
526 
527         if ( ptr->type == IDMEF_DATA_TYPE_TIME && ptr->flags & IDMEF_DATA_OWN_DATA )
528                 idmef_time_destroy(ptr->data.rw_data);
529 
530         else if ( (ptr->type == IDMEF_DATA_TYPE_CHAR_STRING || ptr->type == IDMEF_DATA_TYPE_BYTE_STRING) &&
531              ptr->flags & IDMEF_DATA_OWN_DATA ) {
532                 free(ptr->data.rw_data);
533                 ptr->data.rw_data = NULL;
534         }
535 
536         /*
537          * free() should be done by the caller
538          */
539 }
540 
541 
542 
543 
544 /**
545  * idmef_data_destroy:
546  * @data: Pointer to an #idmef_data_t object.
547  *
548  * Frees @data. The buffer pointed by @data will be freed if
549  * the @data object is marked as _dup or _nodup.
550  */
idmef_data_destroy(idmef_data_t * data)551 void idmef_data_destroy(idmef_data_t *data)
552 {
553         prelude_return_if_fail(data);
554 
555         if ( --data->refcount )
556                 return;
557 
558         idmef_data_destroy_internal(data);
559 
560         if ( data->flags & IDMEF_DATA_OWN_STRUCTURE )
561                 free(data);
562 }
563 
564 
idmef_data_new_char_string_ref_fast(idmef_data_t ** data,const char * ptr,size_t len)565 int idmef_data_new_char_string_ref_fast(idmef_data_t **data, const char *ptr, size_t len)
566 {
567         return idmef_data_new_ptr_ref_fast(data, IDMEF_DATA_TYPE_CHAR_STRING, ptr, len + 1);
568 }
569 
idmef_data_new_char_string_dup_fast(idmef_data_t ** data,const char * ptr,size_t len)570 int idmef_data_new_char_string_dup_fast(idmef_data_t **data, const char *ptr, size_t len)
571 {
572         return idmef_data_new_ptr_dup_fast(data, IDMEF_DATA_TYPE_CHAR_STRING, ptr, len + 1);
573 }
574 
idmef_data_new_char_string_nodup_fast(idmef_data_t ** data,char * ptr,size_t len)575 int idmef_data_new_char_string_nodup_fast(idmef_data_t **data, char *ptr, size_t len)
576 {
577         return idmef_data_new_ptr_nodup_fast(data, IDMEF_DATA_TYPE_CHAR_STRING, ptr, len + 1);
578 }
579 
idmef_data_set_char_string_ref_fast(idmef_data_t * data,const char * ptr,size_t len)580 int idmef_data_set_char_string_ref_fast(idmef_data_t *data, const char *ptr, size_t len)
581 {
582         return idmef_data_set_ptr_ref_fast(data, IDMEF_DATA_TYPE_CHAR_STRING, ptr, len + 1);
583 }
584 
idmef_data_set_char_string_dup_fast(idmef_data_t * data,const char * ptr,size_t len)585 int idmef_data_set_char_string_dup_fast(idmef_data_t *data, const char *ptr, size_t len)
586 {
587         return idmef_data_set_ptr_dup_fast(data, IDMEF_DATA_TYPE_CHAR_STRING, ptr, len + 1);
588 }
589 
idmef_data_set_char_string_nodup_fast(idmef_data_t * data,char * ptr,size_t len)590 int idmef_data_set_char_string_nodup_fast(idmef_data_t *data, char *ptr, size_t len)
591 {
592         return idmef_data_set_ptr_nodup_fast(data, IDMEF_DATA_TYPE_CHAR_STRING, ptr, len + 1);
593 }
594 
595 
idmef_data_new_char_string_ref(idmef_data_t ** data,const char * ptr)596 int idmef_data_new_char_string_ref(idmef_data_t **data, const char *ptr)
597 {
598         prelude_return_val_if_fail(ptr, prelude_error(PRELUDE_ERROR_ASSERTION));
599         return idmef_data_new_char_string_ref_fast(data, ptr, strlen(ptr));
600 }
601 
idmef_data_new_char_string_dup(idmef_data_t ** data,const char * ptr)602 int idmef_data_new_char_string_dup(idmef_data_t **data, const char *ptr)
603 {
604         prelude_return_val_if_fail(ptr, prelude_error(PRELUDE_ERROR_ASSERTION));
605         return idmef_data_new_char_string_dup_fast(data, ptr, strlen(ptr));
606 }
607 
idmef_data_new_char_string_nodup(idmef_data_t ** data,char * ptr)608 int idmef_data_new_char_string_nodup(idmef_data_t **data, char *ptr)
609 {
610         prelude_return_val_if_fail(ptr, prelude_error(PRELUDE_ERROR_ASSERTION));
611         return idmef_data_new_char_string_nodup_fast(data, ptr, strlen(ptr));
612 }
613 
idmef_data_set_char_string_ref(idmef_data_t * data,const char * ptr)614 int idmef_data_set_char_string_ref(idmef_data_t *data, const char *ptr)
615 {
616         prelude_return_val_if_fail(data, prelude_error(PRELUDE_ERROR_ASSERTION));
617         prelude_return_val_if_fail(ptr, prelude_error(PRELUDE_ERROR_ASSERTION));
618 
619         return idmef_data_set_char_string_ref_fast(data, ptr, strlen(ptr));
620 }
621 
idmef_data_set_char_string_dup(idmef_data_t * data,const char * ptr)622 int idmef_data_set_char_string_dup(idmef_data_t *data, const char *ptr)
623 {
624         prelude_return_val_if_fail(data, prelude_error(PRELUDE_ERROR_ASSERTION));
625         prelude_return_val_if_fail(ptr, prelude_error(PRELUDE_ERROR_ASSERTION));
626 
627         return idmef_data_set_char_string_dup_fast(data, ptr, strlen(ptr));
628 }
629 
idmef_data_set_char_string_nodup(idmef_data_t * data,char * ptr)630 int idmef_data_set_char_string_nodup(idmef_data_t *data, char *ptr)
631 {
632         prelude_return_val_if_fail(data, prelude_error(PRELUDE_ERROR_ASSERTION));
633         prelude_return_val_if_fail(ptr, prelude_error(PRELUDE_ERROR_ASSERTION));
634 
635         return idmef_data_set_char_string_nodup_fast(data, ptr, strlen(ptr));
636 }
637 
638 
639 /*
640  *
641  */
idmef_data_new_byte_string_ref(idmef_data_t ** data,const unsigned char * ptr,size_t len)642 int idmef_data_new_byte_string_ref(idmef_data_t **data, const unsigned char *ptr, size_t len)
643 {
644         return idmef_data_new_ptr_ref_fast(data, IDMEF_DATA_TYPE_BYTE_STRING, ptr, len);
645 }
646 
647 
idmef_data_new_byte_string_dup(idmef_data_t ** data,const unsigned char * ptr,size_t len)648 int idmef_data_new_byte_string_dup(idmef_data_t **data, const unsigned char *ptr, size_t len)
649 {
650         return idmef_data_new_ptr_dup_fast(data, IDMEF_DATA_TYPE_BYTE_STRING, ptr, len);
651 }
652 
653 
idmef_data_new_byte_string_nodup(idmef_data_t ** data,unsigned char * ptr,size_t len)654 int idmef_data_new_byte_string_nodup(idmef_data_t **data, unsigned char *ptr, size_t len)
655 {
656         return idmef_data_new_ptr_nodup_fast(data, IDMEF_DATA_TYPE_BYTE_STRING, ptr, len);
657 }
658 
659 
idmef_data_set_byte_string_ref(idmef_data_t * data,const unsigned char * ptr,size_t len)660 int idmef_data_set_byte_string_ref(idmef_data_t *data, const unsigned char *ptr, size_t len)
661 {
662         return idmef_data_set_ptr_ref_fast(data, IDMEF_DATA_TYPE_BYTE_STRING, ptr, len);
663 }
664 
665 
idmef_data_set_byte_string_dup(idmef_data_t * data,const unsigned char * ptr,size_t len)666 int idmef_data_set_byte_string_dup(idmef_data_t *data, const unsigned char *ptr, size_t len)
667 {
668         return idmef_data_set_ptr_dup_fast(data, IDMEF_DATA_TYPE_BYTE_STRING, ptr, len);
669 }
670 
671 
idmef_data_set_byte_string_nodup(idmef_data_t * data,unsigned char * ptr,size_t len)672 int idmef_data_set_byte_string_nodup(idmef_data_t *data, unsigned char *ptr, size_t len)
673 {
674         return idmef_data_set_ptr_nodup_fast(data, IDMEF_DATA_TYPE_BYTE_STRING, ptr, len);
675 }
676 
677 
678 
idmef_data_compare(const idmef_data_t * data1,const idmef_data_t * data2)679 int idmef_data_compare(const idmef_data_t *data1, const idmef_data_t *data2)
680 {
681         if ( ! data1 && ! data2 )
682                 return 0;
683 
684         else if ( ! data1 || ! data2 )
685                 return (data1) ? 1 : -1;
686 
687         else if ( data1->len != data2->len )
688                 return (data1->len > data2->len) ? 1 : -1;
689 
690         else if ( data1->type != data2->type )
691                 return -1;
692 
693         if ( data1->type == IDMEF_DATA_TYPE_TIME )
694                 return idmef_time_compare(data1->data.ro_data, data2->data.ro_data);
695 
696         else if ( data1->type == IDMEF_DATA_TYPE_CHAR_STRING || data1->type == IDMEF_DATA_TYPE_BYTE_STRING )
697                 return memcmp(data1->data.ro_data, data2->data.ro_data, data1->len);
698 
699         else
700                 return memcmp(&data1->data.char_data, &data2->data.char_data, data1->len);
701 }
702