]>
Commit | Line | Data |
---|---|---|
525e6a6e JF |
1 | /* |
2 | * Copyright (c) 2011 Red Hat, Inc. | |
3 | * | |
4 | * All rights reserved. | |
5 | * | |
6 | * Author: Jan Friesse (jfriesse@redhat.com) | |
7 | * | |
8 | * This software licensed under BSD license, the text of which follows: | |
9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions are met: | |
12 | * | |
13 | * - Redistributions of source code must retain the above copyright notice, | |
14 | * this list of conditions and the following disclaimer. | |
15 | * - Redistributions in binary form must reproduce the above copyright notice, | |
16 | * this list of conditions and the following disclaimer in the documentation | |
17 | * and/or other materials provided with the distribution. | |
18 | * - Neither the name of the Red Hat, Inc. nor the names of its | |
19 | * contributors may be used to endorse or promote products derived from this | |
20 | * software without specific prior written permission. | |
21 | * | |
22 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
23 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
24 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
25 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | |
26 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
27 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
28 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
29 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
30 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
31 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF | |
32 | * THE POSSIBILITY OF SUCH DAMAGE. | |
33 | */ | |
34 | ||
35 | #include <config.h> | |
36 | ||
37 | #include <string.h> | |
38 | #include <stdio.h> | |
39 | ||
40 | #include <corosync/corotypes.h> | |
41 | ||
42 | #include <qb/qbdefs.h> | |
43 | #include <corosync/list.h> | |
7e1c9771 | 44 | #include <corosync/icmap.h> |
525e6a6e JF |
45 | |
46 | #define ICMAP_MAX_VALUE_LEN (16*1024) | |
47 | ||
48 | struct icmap_item { | |
49 | char *key_name; | |
50 | icmap_value_types_t type; | |
51 | size_t value_len; | |
52 | char value[]; | |
53 | }; | |
54 | ||
e5a528c5 JF |
55 | struct icmap_map { |
56 | qb_map_t *qb_map; | |
57 | }; | |
58 | ||
59 | static icmap_map_t icmap_global_map; | |
525e6a6e JF |
60 | |
61 | struct icmap_track { | |
62 | char *key_name; | |
63 | int32_t track_type; | |
64 | icmap_notify_fn_t notify_fn; | |
65 | void *user_data; | |
1dcb2d43 | 66 | struct list_head list; |
525e6a6e JF |
67 | }; |
68 | ||
69 | struct icmap_ro_access_item { | |
70 | char *key_name; | |
71 | int prefix; | |
72 | struct list_head list; | |
73 | }; | |
74 | ||
75 | DECLARE_LIST_INIT(icmap_ro_access_item_list_head); | |
1dcb2d43 | 76 | DECLARE_LIST_INIT(icmap_track_list_head); |
525e6a6e JF |
77 | |
78 | /* | |
79 | * Static functions declarations | |
80 | */ | |
81 | ||
82 | /* | |
83 | * Check if key_name is valid icmap key name. Returns 0 on success, and -1 on fail | |
84 | */ | |
85 | static int icmap_check_key_name(const char *key_name); | |
86 | ||
87 | /* | |
88 | * Check that value with given type has correct length value_len. Returns 0 on success, | |
89 | * and -1 on fail | |
90 | */ | |
91 | static int icmap_check_value_len(const void *value, size_t value_len, icmap_value_types_t type); | |
92 | ||
93 | /* | |
94 | * Returns length of value of given type, or 0 for string and binary data type | |
95 | */ | |
96 | static size_t icmap_get_valuetype_len(icmap_value_types_t type); | |
97 | ||
98 | /* | |
99 | * Converts track type of icmap to qb | |
100 | */ | |
101 | static int32_t icmap_tt_to_qbtt(int32_t track_type); | |
102 | ||
103 | /* | |
104 | * Convert track type of qb to icmap | |
105 | */ | |
106 | static int32_t icmap_qbtt_to_tt(int32_t track_type); | |
107 | ||
108 | /* | |
109 | * Checks if item has same value as value with value_len and given type. Returns 0 if not, otherwise !0. | |
110 | */ | |
111 | static int icmap_item_eq(const struct icmap_item *item, const void *value, size_t value_len, icmap_value_types_t type); | |
112 | ||
113 | /* | |
114 | * Checks if given character is valid in key name. Returns 0 if not, otherwise !0. | |
115 | */ | |
116 | static int icmap_is_valid_name_char(char c); | |
117 | ||
118 | /* | |
119 | * Helper for getting integer and float value with given type for key key_name and store it in value. | |
120 | */ | |
e5a528c5 JF |
121 | static cs_error_t icmap_get_int_r( |
122 | const icmap_map_t map, | |
525e6a6e JF |
123 | const char *key_name, |
124 | void *value, | |
125 | icmap_value_types_t type); | |
126 | ||
127 | /* | |
128 | * Function implementation | |
129 | */ | |
130 | static int32_t icmap_tt_to_qbtt(int32_t track_type) | |
131 | { | |
132 | int32_t res = 0; | |
133 | ||
134 | if (track_type & ICMAP_TRACK_DELETE) { | |
135 | res |= QB_MAP_NOTIFY_DELETED; | |
136 | } | |
137 | ||
138 | if (track_type & ICMAP_TRACK_MODIFY) { | |
139 | res |= QB_MAP_NOTIFY_REPLACED; | |
140 | } | |
141 | ||
142 | if (track_type & ICMAP_TRACK_ADD) { | |
143 | res |= QB_MAP_NOTIFY_INSERTED; | |
144 | } | |
145 | ||
146 | if (track_type & ICMAP_TRACK_PREFIX) { | |
147 | res |= QB_MAP_NOTIFY_RECURSIVE; | |
148 | } | |
149 | ||
8a2e9363 | 150 | return (res); |
525e6a6e JF |
151 | } |
152 | ||
153 | static int32_t icmap_qbtt_to_tt(int32_t track_type) | |
154 | { | |
155 | int32_t res = 0; | |
156 | ||
157 | if (track_type & QB_MAP_NOTIFY_DELETED) { | |
158 | res |= ICMAP_TRACK_DELETE; | |
159 | } | |
160 | ||
161 | if (track_type & QB_MAP_NOTIFY_REPLACED) { | |
162 | res |= ICMAP_TRACK_MODIFY; | |
163 | } | |
164 | ||
165 | if (track_type & QB_MAP_NOTIFY_INSERTED) { | |
166 | res |= ICMAP_TRACK_ADD; | |
167 | } | |
168 | ||
169 | if (track_type & QB_MAP_NOTIFY_RECURSIVE) { | |
170 | res |= ICMAP_TRACK_PREFIX; | |
171 | } | |
172 | ||
8a2e9363 | 173 | return (res); |
525e6a6e JF |
174 | } |
175 | ||
176 | static void icmap_map_free_cb(uint32_t event, | |
177 | char* key, void* old_value, | |
178 | void* value, void* user_data) | |
179 | { | |
180 | struct icmap_item *item = (struct icmap_item *)old_value; | |
181 | ||
a1df899d JF |
182 | /* |
183 | * value == old_value -> fast_adjust_int was used, don't free data | |
184 | */ | |
185 | if (item != NULL && value != old_value) { | |
525e6a6e JF |
186 | free(item->key_name); |
187 | free(item); | |
188 | } | |
189 | } | |
190 | ||
e5a528c5 | 191 | cs_error_t icmap_init_r(icmap_map_t *result) |
525e6a6e JF |
192 | { |
193 | int32_t err; | |
194 | ||
e5a528c5 JF |
195 | *result = malloc(sizeof(struct icmap_map)); |
196 | if (*result == NULL) { | |
197 | return (CS_ERR_NO_MEMORY); | |
198 | } | |
199 | ||
200 | (*result)->qb_map = qb_trie_create(); | |
201 | if ((*result)->qb_map == NULL) | |
525e6a6e JF |
202 | return (CS_ERR_INIT); |
203 | ||
e5a528c5 | 204 | err = qb_map_notify_add((*result)->qb_map, NULL, icmap_map_free_cb, QB_MAP_NOTIFY_FREE, NULL); |
525e6a6e JF |
205 | |
206 | return (qb_to_cs_error(err)); | |
207 | } | |
208 | ||
e5a528c5 JF |
209 | cs_error_t icmap_init(void) |
210 | { | |
211 | return (icmap_init_r(&icmap_global_map)); | |
212 | } | |
213 | ||
1dcb2d43 FDN |
214 | static void icmap_set_ro_access_free(void) |
215 | { | |
216 | struct list_head *iter = icmap_ro_access_item_list_head.next; | |
217 | struct icmap_ro_access_item *icmap_ro_ai; | |
218 | ||
219 | while (iter != &icmap_ro_access_item_list_head) { | |
220 | icmap_ro_ai = list_entry(iter, struct icmap_ro_access_item, list); | |
221 | list_del(&icmap_ro_ai->list); | |
222 | free(icmap_ro_ai->key_name); | |
223 | free(icmap_ro_ai); | |
224 | iter = icmap_ro_access_item_list_head.next; | |
225 | } | |
226 | } | |
227 | ||
228 | static void icmap_del_all_track(void) | |
229 | { | |
230 | struct list_head *iter = icmap_track_list_head.next; | |
231 | struct icmap_track *icmap_track; | |
232 | ||
233 | while (iter != &icmap_track_list_head) { | |
234 | icmap_track = list_entry(iter, struct icmap_track, list); | |
235 | icmap_track_delete(icmap_track); | |
236 | iter = icmap_track_list_head.next; | |
237 | } | |
238 | } | |
239 | ||
e5a528c5 JF |
240 | void icmap_fini_r(const icmap_map_t map) |
241 | { | |
242 | ||
243 | qb_map_destroy(map->qb_map); | |
244 | free(map); | |
245 | ||
246 | return; | |
247 | } | |
248 | ||
1dcb2d43 FDN |
249 | void icmap_fini(void) |
250 | { | |
e5a528c5 | 251 | |
1dcb2d43 FDN |
252 | icmap_del_all_track(); |
253 | /* | |
254 | * catch 22 warning: | |
255 | * We need to drop this notify but we can't because it calls icmap_map_free_cb | |
256 | * while destroying the tree to free icmap_item(s). | |
257 | * -> qb_map_notify_del_2(icmap_map, NULL, icmap_map_free_cb, QB_MAP_NOTIFY_FREE, NULL); | |
258 | * and we cannot call it after map_destroy. joy! :) | |
259 | */ | |
e5a528c5 | 260 | icmap_fini_r(icmap_global_map); |
1dcb2d43 | 261 | icmap_set_ro_access_free(); |
e5a528c5 JF |
262 | |
263 | return ; | |
1dcb2d43 FDN |
264 | } |
265 | ||
04ddddd6 JF |
266 | icmap_map_t icmap_get_global_map(void) |
267 | { | |
268 | ||
269 | return (icmap_global_map); | |
270 | } | |
271 | ||
525e6a6e JF |
272 | static int icmap_is_valid_name_char(char c) |
273 | { | |
274 | return ((c >= 'a' && c <= 'z') || | |
275 | (c >= 'A' && c <= 'Z') || | |
276 | (c >= '0' && c <= '9') || | |
277 | c == '.' || c == '_' || c == '-' || c == '/' || c == ':'); | |
278 | } | |
279 | ||
280 | void icmap_convert_name_to_valid_name(char *key_name) | |
281 | { | |
282 | int i; | |
283 | ||
284 | for (i = 0; i < strlen(key_name); i++) { | |
285 | if (!icmap_is_valid_name_char(key_name[i])) { | |
286 | key_name[i] = '_'; | |
287 | } | |
288 | } | |
289 | } | |
290 | ||
291 | static int icmap_check_key_name(const char *key_name) | |
292 | { | |
293 | int i; | |
294 | ||
295 | if ((strlen(key_name) < ICMAP_KEYNAME_MINLEN) || strlen(key_name) > ICMAP_KEYNAME_MAXLEN) { | |
296 | return (-1); | |
297 | } | |
298 | ||
299 | for (i = 0; i < strlen(key_name); i++) { | |
300 | if (!icmap_is_valid_name_char(key_name[i])) { | |
301 | return (-1); | |
302 | } | |
303 | } | |
304 | ||
305 | return (0); | |
306 | } | |
307 | ||
308 | static size_t icmap_get_valuetype_len(icmap_value_types_t type) | |
309 | { | |
841a7a82 | 310 | size_t res = 0; |
525e6a6e JF |
311 | |
312 | switch (type) { | |
313 | case ICMAP_VALUETYPE_INT8: res = sizeof(int8_t); break; | |
314 | case ICMAP_VALUETYPE_UINT8: res = sizeof(uint8_t); break; | |
315 | case ICMAP_VALUETYPE_INT16: res = sizeof(int16_t); break; | |
316 | case ICMAP_VALUETYPE_UINT16: res = sizeof(uint16_t); break; | |
317 | case ICMAP_VALUETYPE_INT32: res = sizeof(int32_t); break; | |
318 | case ICMAP_VALUETYPE_UINT32: res = sizeof(uint32_t); break; | |
319 | case ICMAP_VALUETYPE_INT64: res = sizeof(int64_t); break; | |
320 | case ICMAP_VALUETYPE_UINT64: res = sizeof(uint64_t); break; | |
321 | case ICMAP_VALUETYPE_FLOAT: res = sizeof(float); break; | |
322 | case ICMAP_VALUETYPE_DOUBLE: res = sizeof(double); break; | |
323 | case ICMAP_VALUETYPE_STRING: | |
324 | case ICMAP_VALUETYPE_BINARY: | |
325 | res = 0; | |
326 | break; | |
327 | } | |
328 | ||
329 | return (res); | |
330 | } | |
331 | ||
332 | static int icmap_check_value_len(const void *value, size_t value_len, icmap_value_types_t type) | |
333 | { | |
334 | ||
335 | if (value_len > ICMAP_MAX_VALUE_LEN) { | |
336 | return (-1); | |
337 | } | |
338 | ||
339 | if (type != ICMAP_VALUETYPE_STRING && type != ICMAP_VALUETYPE_BINARY) { | |
340 | if (icmap_get_valuetype_len(type) == value_len) { | |
341 | return (0); | |
342 | } else { | |
343 | return (-1); | |
344 | } | |
345 | } | |
346 | ||
347 | if (type == ICMAP_VALUETYPE_STRING) { | |
624cd439 JF |
348 | /* |
349 | * value_len can be shorter then real string length, but never | |
350 | * longer (+ 1 is because of 0 at the end of string) | |
351 | */ | |
352 | if (value_len > strlen((const char *)value) + 1) { | |
525e6a6e JF |
353 | return (-1); |
354 | } else { | |
355 | return (0); | |
356 | } | |
357 | } | |
358 | ||
359 | return (0); | |
360 | } | |
361 | ||
362 | static int icmap_item_eq(const struct icmap_item *item, const void *value, size_t value_len, icmap_value_types_t type) | |
363 | { | |
364 | size_t ptr_len; | |
365 | ||
366 | if (item->type != type) { | |
367 | return (0); | |
368 | } | |
369 | ||
370 | if (item->type == ICMAP_VALUETYPE_STRING) { | |
371 | ptr_len = strlen((const char *)value); | |
372 | if (ptr_len > value_len) { | |
373 | ptr_len = value_len; | |
374 | } | |
375 | ptr_len++; | |
376 | } else { | |
377 | ptr_len = value_len; | |
378 | } | |
379 | ||
380 | if (item->value_len == ptr_len) { | |
381 | return (memcmp(item->value, value, value_len) == 0); | |
382 | }; | |
383 | ||
384 | return (0); | |
385 | } | |
386 | ||
e5a528c5 JF |
387 | cs_error_t icmap_set_r( |
388 | const icmap_map_t map, | |
525e6a6e JF |
389 | const char *key_name, |
390 | const void *value, | |
391 | size_t value_len, | |
392 | icmap_value_types_t type) | |
393 | { | |
394 | struct icmap_item *item; | |
395 | struct icmap_item *new_item; | |
396 | size_t new_value_len; | |
397 | size_t new_item_size; | |
398 | ||
399 | if (value == NULL || key_name == NULL) { | |
400 | return (CS_ERR_INVALID_PARAM); | |
401 | } | |
402 | ||
403 | if (icmap_check_value_len(value, value_len, type) != 0) { | |
404 | return (CS_ERR_INVALID_PARAM); | |
405 | } | |
406 | ||
e5a528c5 | 407 | item = qb_map_get(map->qb_map, key_name); |
525e6a6e JF |
408 | if (item != NULL) { |
409 | /* | |
410 | * Check that key is really changed | |
411 | */ | |
412 | if (icmap_item_eq(item, value, value_len, type)) { | |
413 | return (CS_OK); | |
414 | } | |
415 | } else { | |
416 | if (icmap_check_key_name(key_name) != 0) { | |
417 | return (CS_ERR_NAME_TOO_LONG); | |
418 | } | |
419 | } | |
420 | ||
421 | if (type == ICMAP_VALUETYPE_BINARY || type == ICMAP_VALUETYPE_STRING) { | |
422 | if (type == ICMAP_VALUETYPE_STRING) { | |
423 | new_value_len = strlen((const char *)value); | |
424 | if (new_value_len > value_len) { | |
425 | new_value_len = value_len; | |
426 | } | |
427 | new_value_len++; | |
428 | } else { | |
429 | new_value_len = value_len; | |
430 | } | |
431 | } else { | |
432 | new_value_len = icmap_get_valuetype_len(type); | |
433 | } | |
434 | ||
435 | new_item_size = sizeof(struct icmap_item) + new_value_len; | |
436 | new_item = malloc(new_item_size); | |
437 | if (new_item == NULL) { | |
438 | return (CS_ERR_NO_MEMORY); | |
439 | } | |
440 | memset(new_item, 0, new_item_size); | |
441 | ||
442 | if (item == NULL) { | |
443 | new_item->key_name = strdup(key_name); | |
444 | if (new_item->key_name == NULL) { | |
445 | free(new_item); | |
446 | return (CS_ERR_NO_MEMORY); | |
447 | } | |
448 | } else { | |
449 | new_item->key_name = item->key_name; | |
450 | item->key_name = NULL; | |
451 | } | |
452 | ||
453 | new_item->type = type; | |
454 | new_item->value_len = new_value_len; | |
455 | ||
456 | memcpy(new_item->value, value, new_value_len); | |
457 | ||
458 | if (new_item->type == ICMAP_VALUETYPE_STRING) { | |
459 | ((char *)new_item->value)[new_value_len - 1] = 0; | |
460 | } | |
461 | ||
e5a528c5 | 462 | qb_map_put(map->qb_map, new_item->key_name, new_item); |
525e6a6e JF |
463 | |
464 | return (CS_OK); | |
465 | } | |
466 | ||
e5a528c5 JF |
467 | cs_error_t icmap_set( |
468 | const char *key_name, | |
469 | const void *value, | |
470 | size_t value_len, | |
471 | icmap_value_types_t type) | |
472 | { | |
473 | ||
474 | return (icmap_set_r(icmap_global_map, key_name, value, value_len, type)); | |
475 | } | |
476 | ||
477 | cs_error_t icmap_set_int8_r(const icmap_map_t map, const char *key_name, int8_t value) | |
478 | { | |
479 | ||
480 | return (icmap_set_r(map, key_name, &value, sizeof(value), ICMAP_VALUETYPE_INT8)); | |
481 | } | |
482 | ||
483 | cs_error_t icmap_set_uint8_r(const icmap_map_t map, const char *key_name, uint8_t value) | |
484 | { | |
485 | ||
486 | return (icmap_set_r(map, key_name, &value, sizeof(value), ICMAP_VALUETYPE_UINT8)); | |
487 | } | |
488 | ||
489 | cs_error_t icmap_set_int16_r(const icmap_map_t map, const char *key_name, int16_t value) | |
490 | { | |
491 | ||
492 | return (icmap_set_r(map,key_name, &value, sizeof(value), ICMAP_VALUETYPE_INT16)); | |
493 | } | |
494 | ||
495 | cs_error_t icmap_set_uint16_r(const icmap_map_t map, const char *key_name, uint16_t value) | |
496 | { | |
497 | ||
498 | return (icmap_set_r(map, key_name, &value, sizeof(value), ICMAP_VALUETYPE_UINT16)); | |
499 | } | |
500 | ||
501 | cs_error_t icmap_set_int32_r(const icmap_map_t map, const char *key_name, int32_t value) | |
502 | { | |
503 | ||
504 | return (icmap_set_r(map, key_name, &value, sizeof(value), ICMAP_VALUETYPE_INT32)); | |
505 | } | |
506 | ||
507 | cs_error_t icmap_set_uint32_r(const icmap_map_t map, const char *key_name, uint32_t value) | |
508 | { | |
509 | ||
510 | return (icmap_set_r(map, key_name, &value, sizeof(value), ICMAP_VALUETYPE_UINT32)); | |
511 | } | |
512 | ||
513 | cs_error_t icmap_set_int64_r(const icmap_map_t map, const char *key_name, int64_t value) | |
514 | { | |
515 | ||
516 | return (icmap_set_r(map, key_name, &value, sizeof(value), ICMAP_VALUETYPE_INT64)); | |
517 | } | |
518 | ||
519 | cs_error_t icmap_set_uint64_r(const icmap_map_t map, const char *key_name, uint64_t value) | |
520 | { | |
521 | ||
522 | return (icmap_set_r(map, key_name, &value, sizeof(value), ICMAP_VALUETYPE_UINT64)); | |
523 | } | |
524 | ||
525 | cs_error_t icmap_set_float_r(const icmap_map_t map, const char *key_name, float value) | |
526 | { | |
527 | ||
528 | return (icmap_set_r(map, key_name, &value, sizeof(value), ICMAP_VALUETYPE_FLOAT)); | |
529 | } | |
530 | ||
531 | cs_error_t icmap_set_double_r(const icmap_map_t map, const char *key_name, double value) | |
532 | { | |
533 | ||
534 | return (icmap_set_r(map, key_name, &value, sizeof(value), ICMAP_VALUETYPE_DOUBLE)); | |
535 | } | |
536 | ||
537 | cs_error_t icmap_set_string_r(const icmap_map_t map, const char *key_name, const char *value) | |
538 | { | |
539 | ||
540 | if (value == NULL) { | |
541 | return (CS_ERR_INVALID_PARAM); | |
542 | } | |
543 | ||
544 | return (icmap_set_r(map, key_name, value, strlen(value), ICMAP_VALUETYPE_STRING)); | |
545 | } | |
546 | ||
525e6a6e JF |
547 | cs_error_t icmap_set_int8(const char *key_name, int8_t value) |
548 | { | |
549 | ||
e5a528c5 | 550 | return (icmap_set_int8_r(icmap_global_map, key_name, value)); |
525e6a6e JF |
551 | } |
552 | ||
553 | cs_error_t icmap_set_uint8(const char *key_name, uint8_t value) | |
554 | { | |
555 | ||
e5a528c5 | 556 | return (icmap_set_uint8_r(icmap_global_map, key_name, value)); |
525e6a6e JF |
557 | } |
558 | ||
559 | cs_error_t icmap_set_int16(const char *key_name, int16_t value) | |
560 | { | |
561 | ||
e5a528c5 | 562 | return (icmap_set_int16_r(icmap_global_map, key_name, value)); |
525e6a6e JF |
563 | } |
564 | ||
565 | cs_error_t icmap_set_uint16(const char *key_name, uint16_t value) | |
566 | { | |
567 | ||
e5a528c5 | 568 | return (icmap_set_uint16_r(icmap_global_map, key_name, value)); |
525e6a6e JF |
569 | } |
570 | ||
571 | cs_error_t icmap_set_int32(const char *key_name, int32_t value) | |
572 | { | |
573 | ||
e5a528c5 | 574 | return (icmap_set_int32_r(icmap_global_map, key_name, value)); |
525e6a6e JF |
575 | } |
576 | ||
577 | cs_error_t icmap_set_uint32(const char *key_name, uint32_t value) | |
578 | { | |
579 | ||
e5a528c5 | 580 | return (icmap_set_uint32_r(icmap_global_map, key_name, value)); |
525e6a6e JF |
581 | } |
582 | ||
583 | cs_error_t icmap_set_int64(const char *key_name, int64_t value) | |
584 | { | |
585 | ||
e5a528c5 | 586 | return (icmap_set_int64_r(icmap_global_map, key_name, value)); |
525e6a6e JF |
587 | } |
588 | ||
589 | cs_error_t icmap_set_uint64(const char *key_name, uint64_t value) | |
590 | { | |
591 | ||
e5a528c5 | 592 | return (icmap_set_uint64_r(icmap_global_map, key_name, value)); |
525e6a6e JF |
593 | } |
594 | ||
595 | cs_error_t icmap_set_float(const char *key_name, float value) | |
596 | { | |
597 | ||
e5a528c5 | 598 | return (icmap_set_float_r(icmap_global_map, key_name, value)); |
525e6a6e JF |
599 | } |
600 | ||
601 | cs_error_t icmap_set_double(const char *key_name, double value) | |
602 | { | |
603 | ||
e5a528c5 | 604 | return (icmap_set_double_r(icmap_global_map, key_name, value)); |
525e6a6e JF |
605 | } |
606 | ||
607 | cs_error_t icmap_set_string(const char *key_name, const char *value) | |
608 | { | |
609 | ||
e5a528c5 | 610 | return (icmap_set_string_r(icmap_global_map, key_name, value)); |
525e6a6e JF |
611 | } |
612 | ||
e5a528c5 | 613 | cs_error_t icmap_delete_r(const icmap_map_t map, const char *key_name) |
525e6a6e JF |
614 | { |
615 | struct icmap_item *item; | |
616 | ||
617 | if (key_name == NULL) { | |
618 | return (CS_ERR_INVALID_PARAM); | |
619 | } | |
620 | ||
e5a528c5 | 621 | item = qb_map_get(map->qb_map, key_name); |
525e6a6e JF |
622 | if (item == NULL) { |
623 | return (CS_ERR_NOT_EXIST); | |
624 | } | |
625 | ||
e5a528c5 | 626 | if (qb_map_rm(map->qb_map, item->key_name) != QB_TRUE) { |
525e6a6e JF |
627 | return (CS_ERR_NOT_EXIST); |
628 | } | |
629 | ||
630 | return (CS_OK); | |
631 | } | |
632 | ||
e5a528c5 JF |
633 | cs_error_t icmap_delete(const char *key_name) |
634 | { | |
635 | ||
636 | return (icmap_delete_r(icmap_global_map, key_name)); | |
637 | } | |
638 | ||
639 | cs_error_t icmap_get_r( | |
640 | const icmap_map_t map, | |
525e6a6e JF |
641 | const char *key_name, |
642 | void *value, | |
643 | size_t *value_len, | |
644 | icmap_value_types_t *type) | |
645 | { | |
646 | struct icmap_item *item; | |
647 | ||
648 | if (key_name == NULL) { | |
649 | return (CS_ERR_INVALID_PARAM); | |
650 | } | |
651 | ||
e5a528c5 | 652 | item = qb_map_get(map->qb_map, key_name); |
525e6a6e JF |
653 | if (item == NULL) { |
654 | return (CS_ERR_NOT_EXIST); | |
655 | } | |
656 | ||
657 | if (type != NULL) { | |
658 | *type = item->type; | |
659 | } | |
660 | ||
661 | if (value == NULL) { | |
662 | if (value_len != NULL) { | |
663 | *value_len = item->value_len; | |
664 | } | |
665 | } else { | |
666 | if (value_len == NULL || *value_len < item->value_len) { | |
667 | return (CS_ERR_INVALID_PARAM); | |
668 | } | |
669 | ||
670 | *value_len = item->value_len; | |
671 | ||
672 | memcpy(value, item->value, item->value_len); | |
673 | } | |
674 | ||
675 | return (CS_OK); | |
676 | } | |
677 | ||
e5a528c5 JF |
678 | cs_error_t icmap_get( |
679 | const char *key_name, | |
680 | void *value, | |
681 | size_t *value_len, | |
682 | icmap_value_types_t *type) | |
683 | { | |
684 | ||
685 | return (icmap_get_r(icmap_global_map, key_name, value, value_len, type)); | |
686 | } | |
687 | ||
688 | static cs_error_t icmap_get_int_r( | |
689 | const icmap_map_t map, | |
525e6a6e JF |
690 | const char *key_name, |
691 | void *value, | |
692 | icmap_value_types_t type) | |
693 | { | |
694 | char key_value[16]; | |
695 | size_t key_size; | |
696 | cs_error_t err; | |
697 | icmap_value_types_t key_type; | |
698 | ||
699 | key_size = sizeof(key_value); | |
700 | memset(key_value, 0, key_size); | |
701 | ||
702 | err = icmap_get(key_name, key_value, &key_size, &key_type); | |
703 | if (err != CS_OK) | |
704 | return (err); | |
705 | ||
706 | if (key_type != type) { | |
707 | return (CS_ERR_INVALID_PARAM); | |
708 | } | |
709 | ||
710 | memcpy(value, key_value, icmap_get_valuetype_len(key_type)); | |
711 | ||
712 | return (CS_OK); | |
713 | } | |
714 | ||
e5a528c5 JF |
715 | cs_error_t icmap_get_int8_r(const icmap_map_t map, const char *key_name, int8_t *i8) |
716 | { | |
717 | ||
718 | return (icmap_get_int_r(map, key_name, i8, ICMAP_VALUETYPE_INT8)); | |
719 | } | |
720 | ||
721 | cs_error_t icmap_get_uint8_r(const icmap_map_t map, const char *key_name, uint8_t *u8) | |
722 | { | |
723 | ||
724 | return (icmap_get_int_r(map, key_name, u8, ICMAP_VALUETYPE_UINT8)); | |
725 | } | |
726 | ||
727 | cs_error_t icmap_get_int16_r(const icmap_map_t map, const char *key_name, int16_t *i16) | |
728 | { | |
729 | ||
730 | return (icmap_get_int_r(map, key_name, i16, ICMAP_VALUETYPE_INT16)); | |
731 | } | |
732 | ||
733 | cs_error_t icmap_get_uint16_r(const icmap_map_t map, const char *key_name, uint16_t *u16) | |
734 | { | |
735 | ||
736 | return (icmap_get_int_r(map, key_name, u16, ICMAP_VALUETYPE_UINT16)); | |
737 | } | |
738 | ||
739 | cs_error_t icmap_get_int32_r(const icmap_map_t map, const char *key_name, int32_t *i32) | |
740 | { | |
741 | ||
742 | return (icmap_get_int_r(map, key_name, i32, ICMAP_VALUETYPE_INT32)); | |
743 | } | |
744 | ||
745 | cs_error_t icmap_get_uint32_r(const icmap_map_t map, const char *key_name, uint32_t *u32) | |
746 | { | |
747 | ||
748 | return (icmap_get_int_r(map, key_name, u32, ICMAP_VALUETYPE_UINT32)); | |
749 | } | |
750 | ||
751 | cs_error_t icmap_get_int64_r(const icmap_map_t map, const char *key_name, int64_t *i64) | |
752 | { | |
753 | ||
754 | return(icmap_get_int_r(map, key_name, i64, ICMAP_VALUETYPE_INT64)); | |
755 | } | |
756 | ||
757 | cs_error_t icmap_get_uint64_r(const icmap_map_t map, const char *key_name, uint64_t *u64) | |
758 | { | |
759 | ||
760 | return (icmap_get_int_r(map, key_name, u64, ICMAP_VALUETYPE_UINT64)); | |
761 | } | |
762 | ||
763 | cs_error_t icmap_get_float_r(const icmap_map_t map, const char *key_name, float *flt) | |
764 | { | |
765 | ||
766 | return (icmap_get_int_r(map, key_name, flt, ICMAP_VALUETYPE_FLOAT)); | |
767 | } | |
768 | ||
769 | cs_error_t icmap_get_double_r(const icmap_map_t map, const char *key_name, double *dbl) | |
770 | { | |
771 | ||
772 | return (icmap_get_int_r(map, key_name, dbl, ICMAP_VALUETYPE_DOUBLE)); | |
773 | } | |
774 | ||
525e6a6e JF |
775 | cs_error_t icmap_get_int8(const char *key_name, int8_t *i8) |
776 | { | |
777 | ||
e5a528c5 | 778 | return (icmap_get_int8_r(icmap_global_map, key_name, i8)); |
525e6a6e JF |
779 | } |
780 | ||
781 | cs_error_t icmap_get_uint8(const char *key_name, uint8_t *u8) | |
782 | { | |
783 | ||
e5a528c5 | 784 | return (icmap_get_uint8_r(icmap_global_map, key_name, u8)); |
525e6a6e JF |
785 | } |
786 | ||
787 | cs_error_t icmap_get_int16(const char *key_name, int16_t *i16) | |
788 | { | |
789 | ||
e5a528c5 | 790 | return (icmap_get_int16_r(icmap_global_map, key_name, i16)); |
525e6a6e JF |
791 | } |
792 | ||
793 | cs_error_t icmap_get_uint16(const char *key_name, uint16_t *u16) | |
794 | { | |
795 | ||
e5a528c5 | 796 | return (icmap_get_uint16_r(icmap_global_map, key_name, u16)); |
525e6a6e JF |
797 | } |
798 | ||
799 | cs_error_t icmap_get_int32(const char *key_name, int32_t *i32) | |
800 | { | |
801 | ||
e5a528c5 | 802 | return (icmap_get_int32_r(icmap_global_map, key_name, i32)); |
525e6a6e JF |
803 | } |
804 | ||
805 | cs_error_t icmap_get_uint32(const char *key_name, uint32_t *u32) | |
806 | { | |
807 | ||
e5a528c5 | 808 | return (icmap_get_uint32_r(icmap_global_map, key_name, u32)); |
525e6a6e JF |
809 | } |
810 | ||
811 | cs_error_t icmap_get_int64(const char *key_name, int64_t *i64) | |
812 | { | |
813 | ||
e5a528c5 | 814 | return(icmap_get_int64_r(icmap_global_map, key_name, i64)); |
525e6a6e JF |
815 | } |
816 | ||
817 | cs_error_t icmap_get_uint64(const char *key_name, uint64_t *u64) | |
818 | { | |
819 | ||
e5a528c5 | 820 | return (icmap_get_uint64_r(icmap_global_map, key_name, u64)); |
525e6a6e JF |
821 | } |
822 | ||
823 | cs_error_t icmap_get_float(const char *key_name, float *flt) | |
824 | { | |
825 | ||
e5a528c5 | 826 | return (icmap_get_float_r(icmap_global_map, key_name, flt)); |
525e6a6e JF |
827 | } |
828 | ||
829 | cs_error_t icmap_get_double(const char *key_name, double *dbl) | |
830 | { | |
831 | ||
e5a528c5 | 832 | return (icmap_get_double_r(icmap_global_map, key_name, dbl)); |
525e6a6e JF |
833 | } |
834 | ||
835 | cs_error_t icmap_get_string(const char *key_name, char **str) | |
836 | { | |
837 | cs_error_t res; | |
838 | size_t str_len; | |
839 | icmap_value_types_t type; | |
840 | ||
841 | res = icmap_get(key_name, NULL, &str_len, &type); | |
842 | if (res != CS_OK || type != ICMAP_VALUETYPE_STRING) { | |
843 | if (res == CS_OK) { | |
844 | res = CS_ERR_INVALID_PARAM; | |
845 | } | |
846 | ||
847 | goto return_error; | |
848 | } | |
849 | ||
850 | *str = malloc(str_len); | |
851 | if (*str == NULL) { | |
852 | res = CS_ERR_NO_MEMORY; | |
853 | ||
854 | goto return_error; | |
855 | } | |
856 | ||
857 | res = icmap_get(key_name, *str, &str_len, &type); | |
858 | if (res != CS_OK) { | |
859 | free(*str); | |
860 | goto return_error; | |
861 | } | |
862 | ||
863 | return (CS_OK); | |
864 | ||
865 | return_error: | |
866 | return (res); | |
867 | } | |
868 | ||
e5a528c5 JF |
869 | cs_error_t icmap_adjust_int_r( |
870 | const icmap_map_t map, | |
525e6a6e JF |
871 | const char *key_name, |
872 | int32_t step) | |
873 | { | |
874 | struct icmap_item *item; | |
875 | uint8_t u8; | |
876 | uint16_t u16; | |
877 | uint32_t u32; | |
878 | uint64_t u64; | |
879 | cs_error_t err = CS_OK; | |
880 | ||
881 | if (key_name == NULL) { | |
882 | return (CS_ERR_INVALID_PARAM); | |
883 | } | |
884 | ||
e5a528c5 | 885 | item = qb_map_get(map->qb_map, key_name); |
525e6a6e JF |
886 | if (item == NULL) { |
887 | return (CS_ERR_NOT_EXIST); | |
888 | } | |
889 | ||
890 | switch (item->type) { | |
891 | case ICMAP_VALUETYPE_INT8: | |
892 | case ICMAP_VALUETYPE_UINT8: | |
893 | memcpy(&u8, item->value, sizeof(u8)); | |
894 | u8 += step; | |
895 | err = icmap_set(key_name, &u8, sizeof(u8), item->type); | |
896 | break; | |
897 | case ICMAP_VALUETYPE_INT16: | |
898 | case ICMAP_VALUETYPE_UINT16: | |
899 | memcpy(&u16, item->value, sizeof(u16)); | |
900 | u16 += step; | |
901 | err = icmap_set(key_name, &u16, sizeof(u16), item->type); | |
902 | break; | |
903 | case ICMAP_VALUETYPE_INT32: | |
904 | case ICMAP_VALUETYPE_UINT32: | |
905 | memcpy(&u32, item->value, sizeof(u32)); | |
906 | u32 += step; | |
907 | err = icmap_set(key_name, &u32, sizeof(u32), item->type); | |
908 | break; | |
909 | case ICMAP_VALUETYPE_INT64: | |
910 | case ICMAP_VALUETYPE_UINT64: | |
911 | memcpy(&u64, item->value, sizeof(u64)); | |
912 | u64 += step; | |
913 | err = icmap_set(key_name, &u64, sizeof(u64), item->type); | |
914 | break; | |
915 | case ICMAP_VALUETYPE_FLOAT: | |
916 | case ICMAP_VALUETYPE_DOUBLE: | |
917 | case ICMAP_VALUETYPE_STRING: | |
918 | case ICMAP_VALUETYPE_BINARY: | |
919 | err = CS_ERR_INVALID_PARAM; | |
920 | break; | |
921 | } | |
922 | ||
923 | return (err); | |
924 | } | |
925 | ||
e5a528c5 JF |
926 | cs_error_t icmap_adjust_int( |
927 | const char *key_name, | |
928 | int32_t step) | |
929 | { | |
930 | ||
931 | return (icmap_adjust_int_r(icmap_global_map, key_name, step)); | |
932 | } | |
933 | ||
934 | cs_error_t icmap_fast_adjust_int_r( | |
935 | const icmap_map_t map, | |
a1df899d JF |
936 | const char *key_name, |
937 | int32_t step) | |
938 | { | |
939 | struct icmap_item *item; | |
940 | cs_error_t err = CS_OK; | |
941 | ||
942 | if (key_name == NULL) { | |
943 | return (CS_ERR_INVALID_PARAM); | |
944 | } | |
945 | ||
e5a528c5 | 946 | item = qb_map_get(map->qb_map, key_name); |
a1df899d JF |
947 | if (item == NULL) { |
948 | return (CS_ERR_NOT_EXIST); | |
949 | } | |
950 | ||
951 | switch (item->type) { | |
952 | case ICMAP_VALUETYPE_INT8: | |
953 | case ICMAP_VALUETYPE_UINT8: | |
954 | *(uint8_t *)item->value += step; | |
955 | break; | |
956 | case ICMAP_VALUETYPE_INT16: | |
957 | case ICMAP_VALUETYPE_UINT16: | |
958 | *(uint16_t *)item->value += step; | |
959 | break; | |
960 | case ICMAP_VALUETYPE_INT32: | |
961 | case ICMAP_VALUETYPE_UINT32: | |
962 | *(uint32_t *)item->value += step; | |
963 | break; | |
964 | case ICMAP_VALUETYPE_INT64: | |
965 | case ICMAP_VALUETYPE_UINT64: | |
966 | *(uint64_t *)item->value += step; | |
967 | break; | |
968 | case ICMAP_VALUETYPE_FLOAT: | |
969 | case ICMAP_VALUETYPE_DOUBLE: | |
970 | case ICMAP_VALUETYPE_STRING: | |
971 | case ICMAP_VALUETYPE_BINARY: | |
972 | err = CS_ERR_INVALID_PARAM; | |
973 | break; | |
974 | } | |
975 | ||
976 | if (err == CS_OK) { | |
e5a528c5 | 977 | qb_map_put(map->qb_map, item->key_name, item); |
a1df899d JF |
978 | } |
979 | ||
980 | return (err); | |
981 | } | |
982 | ||
e5a528c5 JF |
983 | cs_error_t icmap_fast_adjust_int( |
984 | const char *key_name, | |
985 | int32_t step) | |
986 | { | |
987 | ||
988 | return (icmap_fast_adjust_int_r(icmap_global_map, key_name, step)); | |
989 | } | |
990 | ||
991 | cs_error_t icmap_inc_r(const icmap_map_t map, const char *key_name) | |
992 | { | |
993 | return (icmap_adjust_int_r(map, key_name, 1)); | |
994 | } | |
995 | ||
525e6a6e JF |
996 | cs_error_t icmap_inc(const char *key_name) |
997 | { | |
e5a528c5 JF |
998 | return (icmap_inc_r(icmap_global_map, key_name)); |
999 | } | |
1000 | ||
1001 | cs_error_t icmap_dec_r(const icmap_map_t map, const char *key_name) | |
1002 | { | |
1003 | return (icmap_adjust_int_r(map, key_name, -1)); | |
525e6a6e JF |
1004 | } |
1005 | ||
1006 | cs_error_t icmap_dec(const char *key_name) | |
1007 | { | |
e5a528c5 JF |
1008 | return (icmap_dec_r(icmap_global_map, key_name)); |
1009 | } | |
1010 | ||
1011 | cs_error_t icmap_fast_inc_r(const icmap_map_t map, const char *key_name) | |
1012 | { | |
1013 | return (icmap_fast_adjust_int_r(map, key_name, 1)); | |
525e6a6e JF |
1014 | } |
1015 | ||
a1df899d JF |
1016 | cs_error_t icmap_fast_inc(const char *key_name) |
1017 | { | |
e5a528c5 JF |
1018 | return (icmap_fast_inc_r(icmap_global_map, key_name)); |
1019 | } | |
1020 | ||
1021 | cs_error_t icmap_fast_dec_r(const icmap_map_t map, const char *key_name) | |
1022 | { | |
1023 | return (icmap_fast_adjust_int_r(map, key_name, -1)); | |
a1df899d JF |
1024 | } |
1025 | ||
1026 | cs_error_t icmap_fast_dec(const char *key_name) | |
1027 | { | |
e5a528c5 JF |
1028 | return (icmap_fast_dec_r(icmap_global_map, key_name)); |
1029 | } | |
1030 | ||
1031 | icmap_iter_t icmap_iter_init_r(const icmap_map_t map, const char *prefix) | |
1032 | { | |
1033 | return (qb_map_pref_iter_create(map->qb_map, prefix)); | |
a1df899d JF |
1034 | } |
1035 | ||
525e6a6e JF |
1036 | icmap_iter_t icmap_iter_init(const char *prefix) |
1037 | { | |
e5a528c5 | 1038 | return (icmap_iter_init_r(icmap_global_map, prefix)); |
525e6a6e JF |
1039 | } |
1040 | ||
e5a528c5 | 1041 | |
525e6a6e JF |
1042 | const char *icmap_iter_next(icmap_iter_t iter, size_t *value_len, icmap_value_types_t *type) |
1043 | { | |
1044 | struct icmap_item *item; | |
1045 | const char *res; | |
1046 | ||
1047 | res = qb_map_iter_next(iter, (void **)&item); | |
1048 | if (res == NULL) { | |
1049 | return (res); | |
1050 | } | |
1051 | ||
1052 | if (value_len != NULL) { | |
1053 | *value_len = item->value_len; | |
1054 | } | |
1055 | ||
1056 | if (type != NULL) { | |
1057 | *type = item->type; | |
1058 | } | |
1059 | ||
1060 | return (res); | |
1061 | } | |
1062 | ||
1063 | void icmap_iter_finalize(icmap_iter_t iter) | |
1064 | { | |
1065 | qb_map_iter_free(iter); | |
1066 | } | |
1067 | ||
1068 | static void icmap_notify_fn(uint32_t event, char *key, void *old_value, void *value, void *user_data) | |
1069 | { | |
1070 | icmap_track_t icmap_track = (icmap_track_t)user_data; | |
1071 | struct icmap_item *new_item = (struct icmap_item *)value; | |
1072 | struct icmap_item *old_item = (struct icmap_item *)old_value; | |
1073 | struct icmap_notify_value new_val; | |
1074 | struct icmap_notify_value old_val; | |
1075 | ||
1076 | if (value == NULL && old_value == NULL) { | |
1077 | return ; | |
1078 | } | |
1079 | ||
1080 | if (new_item != NULL) { | |
1081 | new_val.type = new_item->type; | |
1082 | new_val.len = new_item->value_len; | |
1083 | new_val.data = new_item->value; | |
1084 | } else { | |
1085 | memset(&new_val, 0, sizeof(new_val)); | |
1086 | } | |
1087 | ||
a1df899d JF |
1088 | /* |
1089 | * old_item == new_item if fast functions are used -> don't fill old value | |
1090 | */ | |
1091 | if (old_item != NULL && old_item != new_item) { | |
525e6a6e JF |
1092 | old_val.type = old_item->type; |
1093 | old_val.len = old_item->value_len; | |
1094 | old_val.data = old_item->value; | |
1095 | } else { | |
1096 | memset(&old_val, 0, sizeof(old_val)); | |
1097 | } | |
1098 | ||
1099 | icmap_track->notify_fn(icmap_qbtt_to_tt(event), | |
1100 | key, | |
1101 | new_val, | |
1102 | old_val, | |
1103 | icmap_track->user_data); | |
1104 | } | |
1105 | ||
1106 | cs_error_t icmap_track_add( | |
1107 | const char *key_name, | |
1108 | int32_t track_type, | |
1109 | icmap_notify_fn_t notify_fn, | |
1110 | void *user_data, | |
1111 | icmap_track_t *icmap_track) | |
1112 | { | |
1113 | int32_t err; | |
1114 | ||
1115 | if (notify_fn == NULL || icmap_track == NULL) { | |
1116 | return (CS_ERR_INVALID_PARAM); | |
1117 | } | |
1118 | ||
1119 | if ((track_type & ~(ICMAP_TRACK_ADD | ICMAP_TRACK_DELETE | ICMAP_TRACK_MODIFY | ICMAP_TRACK_PREFIX)) != 0) { | |
1120 | return (CS_ERR_INVALID_PARAM); | |
1121 | } | |
1122 | ||
1123 | *icmap_track = malloc(sizeof(**icmap_track)); | |
1124 | if (*icmap_track == NULL) { | |
1125 | return (CS_ERR_NO_MEMORY); | |
1126 | } | |
1127 | memset(*icmap_track, 0, sizeof(**icmap_track)); | |
1128 | ||
1129 | if (key_name != NULL) { | |
1130 | (*icmap_track)->key_name = strdup(key_name); | |
1131 | }; | |
1132 | ||
1133 | (*icmap_track)->track_type = track_type; | |
1134 | (*icmap_track)->notify_fn = notify_fn; | |
1135 | (*icmap_track)->user_data = user_data; | |
1136 | ||
e5a528c5 | 1137 | if ((err = qb_map_notify_add(icmap_global_map->qb_map, (*icmap_track)->key_name, icmap_notify_fn, |
525e6a6e JF |
1138 | icmap_tt_to_qbtt(track_type), *icmap_track)) != 0) { |
1139 | free((*icmap_track)->key_name); | |
1140 | free(*icmap_track); | |
1141 | ||
1142 | return (qb_to_cs_error(err)); | |
1143 | } | |
1144 | ||
1dcb2d43 FDN |
1145 | list_init(&(*icmap_track)->list); |
1146 | list_add (&(*icmap_track)->list, &icmap_track_list_head); | |
1147 | ||
525e6a6e JF |
1148 | return (CS_OK); |
1149 | } | |
1150 | ||
1151 | cs_error_t icmap_track_delete(icmap_track_t icmap_track) | |
1152 | { | |
1153 | int32_t err; | |
1154 | ||
e5a528c5 | 1155 | if ((err = qb_map_notify_del_2(icmap_global_map->qb_map, icmap_track->key_name, |
525e6a6e JF |
1156 | icmap_notify_fn, icmap_tt_to_qbtt(icmap_track->track_type), icmap_track)) != 0) { |
1157 | return (qb_to_cs_error(err)); | |
1158 | } | |
1159 | ||
1dcb2d43 | 1160 | list_del(&icmap_track->list); |
525e6a6e JF |
1161 | free(icmap_track->key_name); |
1162 | free(icmap_track); | |
1163 | ||
1164 | return (CS_OK); | |
1165 | } | |
1166 | ||
1167 | void *icmap_track_get_user_data(icmap_track_t icmap_track) | |
1168 | { | |
1169 | return (icmap_track->user_data); | |
1170 | } | |
1171 | ||
1172 | cs_error_t icmap_set_ro_access(const char *key_name, int prefix, int ro_access) | |
1173 | { | |
1174 | struct list_head *iter; | |
1175 | struct icmap_ro_access_item *icmap_ro_ai; | |
1176 | ||
1177 | for (iter = icmap_ro_access_item_list_head.next; iter != &icmap_ro_access_item_list_head; iter = iter->next) { | |
1178 | icmap_ro_ai = list_entry(iter, struct icmap_ro_access_item, list); | |
1179 | ||
1180 | if (icmap_ro_ai->prefix == prefix && strcmp(key_name, icmap_ro_ai->key_name) == 0) { | |
1181 | /* | |
1182 | * We found item | |
1183 | */ | |
1184 | if (ro_access) { | |
1185 | return (CS_ERR_EXIST); | |
1186 | } else { | |
1187 | list_del(&icmap_ro_ai->list); | |
f2444eff | 1188 | free(icmap_ro_ai->key_name); |
525e6a6e JF |
1189 | free(icmap_ro_ai); |
1190 | ||
1191 | return (CS_OK); | |
1192 | } | |
1193 | } | |
1194 | } | |
1195 | ||
1196 | if (!ro_access) { | |
1197 | return (CS_ERR_NOT_EXIST); | |
1198 | } | |
1199 | ||
1200 | icmap_ro_ai = malloc(sizeof(*icmap_ro_ai)); | |
1201 | if (icmap_ro_ai == NULL) { | |
1202 | return (CS_ERR_NO_MEMORY); | |
1203 | } | |
1204 | ||
1205 | memset(icmap_ro_ai, 0, sizeof(*icmap_ro_ai)); | |
1206 | icmap_ro_ai->key_name = strdup(key_name); | |
1207 | if (icmap_ro_ai->key_name == NULL) { | |
1208 | free(icmap_ro_ai); | |
1209 | return (CS_ERR_NO_MEMORY); | |
1210 | } | |
1211 | ||
1212 | icmap_ro_ai->prefix = prefix; | |
1213 | list_init(&icmap_ro_ai->list); | |
1214 | list_add (&icmap_ro_ai->list, &icmap_ro_access_item_list_head); | |
1215 | ||
1216 | return (CS_OK); | |
1217 | } | |
1218 | ||
1219 | int icmap_is_key_ro(const char *key_name) | |
1220 | { | |
1221 | struct list_head *iter; | |
1222 | struct icmap_ro_access_item *icmap_ro_ai; | |
1223 | ||
1224 | for (iter = icmap_ro_access_item_list_head.next; iter != &icmap_ro_access_item_list_head; iter = iter->next) { | |
1225 | icmap_ro_ai = list_entry(iter, struct icmap_ro_access_item, list); | |
1226 | ||
1227 | if (icmap_ro_ai->prefix) { | |
1228 | if (strlen(icmap_ro_ai->key_name) > strlen(key_name)) | |
1229 | continue; | |
1230 | ||
1231 | if (strncmp(icmap_ro_ai->key_name, key_name, strlen(icmap_ro_ai->key_name)) == 0) { | |
1232 | return (CS_TRUE); | |
1233 | } | |
1234 | } else { | |
1235 | if (strcmp(icmap_ro_ai->key_name, key_name) == 0) { | |
1236 | return (CS_TRUE); | |
1237 | } | |
1238 | } | |
1239 | } | |
1240 | ||
1241 | return (CS_FALSE); | |
1242 | ||
1243 | } |