Line data Source code
1 : /**
2 : * @file
3 : *
4 : * @brief Methods for Key manipulation.
5 : *
6 : * @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
7 : */
8 :
9 :
10 : #ifdef HAVE_KDBCONFIG_H
11 : #include "kdbconfig.h"
12 : #endif
13 :
14 : #if DEBUG && defined(HAVE_STDIO_H)
15 : #include <stdio.h>
16 : #endif
17 :
18 : #ifdef HAVE_STDARG_H
19 : #include <stdarg.h>
20 : #endif
21 :
22 : #ifdef HAVE_STRING_H
23 : #include <string.h>
24 : #endif
25 :
26 : #ifdef HAVE_STDLIB_H
27 : #include <stdlib.h>
28 : #endif
29 :
30 : #include "kdb.h"
31 : #include "kdbprivate.h"
32 :
33 :
34 : /**
35 : * @defgroup key Key
36 : *
37 : * @brief Key is an essential class that encapsulates key @link keyname name @endlink,
38 : * @link keyvalue value @endlink and @link keymeta metainfo @endlink.
39 : *
40 : * To use it include:
41 : * @code
42 : #include <kdb.h>
43 : * @endcode
44 : *
45 : * Key properties are:
46 : * - @link keyname Key name @endlink
47 : * - @link keyvalue Key value @endlink
48 : * - @link keymeta Key metadata @endlink, including but not limited to:
49 : * - @link keyGetComment() Key comment @endlink
50 : * - @link keyGetOwner() Key owner @endlink
51 : * - @link keymeta UID, GID and filesystem-like mode permissions @endlink
52 : * - @link keymeta Mode, change and modification times @endlink
53 : *
54 : * @par ABI
55 : * Due to ABI compatibility, the @p Key structure is not defined in kdb.h,
56 : * only declared. So you can only declare @p pointers to @p Keys in your
57 : * program, and allocate and free memory for them with keyNew()
58 : * and keyDel() respectively.
59 : *
60 : *
61 : * @par Reference Counting
62 : * Every key has its reference counter (see keyGetRef() for longer
63 : * explanation) that will be initialized
64 : * with 0, that means a subsequent call of keyDel() will delete
65 : * the key. If you append the key to a keyset the reference counter
66 : * will be incremented by one (see keyIncRef()) and the key can't be
67 : * deleted by a keyDel().
68 : *
69 : * @par
70 : * As you can imagine this refcounting allows you to put the Key in your
71 : * own data structures.
72 : * It can be a very powerful feature, e.g. if you need your own-defined
73 : * ordering or different Models of your configuration.
74 : */
75 :
76 :
77 : /*
78 : * @internal
79 : *
80 : * Allocates and initializes a key
81 : * @returns 0 if allocation did not work, the key otherwise
82 : */
83 9617082 : static Key * elektraKeyMalloc (void)
84 : {
85 9617082 : Key * key = (Key *) elektraMalloc (sizeof (Key));
86 9617082 : if (!key) return 0;
87 9617082 : keyInit (key);
88 :
89 9617082 : return key;
90 : }
91 :
92 :
93 : /**
94 : * A practical way to fully create a Key object in one step.
95 : *
96 : * To just get a key object, simple do:
97 : *
98 : * @snippet keyNew.c Simple
99 : *
100 : * keyNew() allocates memory for a key object and keyDel() cleans
101 : * everything up.
102 : *
103 : * We can also give an empty key name and a KEY_END tag with the same
104 : * effect as before:
105 : *
106 : * @snippet keyNew.c Alternative
107 : *
108 : * But we can also give the key a proper name right from the start:
109 : *
110 : * @snippet keyNew.c With Name
111 : *
112 : * If you want the key object to contain a name, value, comment and other
113 : * meta info read on.
114 : *
115 : * @note When you already have a key with similar properties its
116 : * easier to keyDup() the key.
117 : *
118 : * You can call keyNew() in many different ways depending on the attribute tags you
119 : * pass as parameters. Tags are represented as #keyswitch_t values, and
120 : * tell keyNew() which Key attribute comes next.
121 : * The Key attribute tags are the following:
122 : * - ::KEY_VALUE \n
123 : * Next parameter is a pointer to the value that will be used.
124 : * If no ::KEY_BINARY was used before, a string is assumed.
125 : * @snippet keyNew.c With Value
126 : * - ::KEY_SIZE \n
127 : * Define a maximum length of the value. This is only used when setting
128 : * a binary key.
129 : * @snippet keyNew.c With Size
130 : * - ::KEY_META \n
131 : * Next two parameter is a metaname and a metavalue. See keySetMeta().
132 : * @snippet keyNew.c With Meta
133 : * - ::KEY_END \n
134 : * Must be the last parameter passed to keyNew(). It is always
135 : * required, unless the @p keyName is 0.
136 : * - ::KEY_FLAGS \n
137 : * Bitwise disjunction of flags, which don't require one or more values.
138 : * recommended way to set multiple flags. overrides previously defined flags.
139 : * @snippet keyNew.c With Flags
140 : * - ::KEY_BINARY \n
141 : * Allows one to change the key to a binary key.
142 : * Make sure that you also pass ::KEY_SIZE before you set the value.
143 : * Otherwise it will be cut off with first \\0 in the string.
144 : * So this flag toggle from keySetString() to keySetBinary().
145 : * If no value (nor size) is given, it will be a NULL key.
146 : * @snippet keyNew.c With Binary
147 : * - ::KEY_CASCADING_NAME allow the name to start with /
148 : * useful for ksLookup() and kdbGet() parent/lookup keys
149 : * - ::KEY_META_NAME allow the name to start with arbitrary namespaces
150 : * useful to compare with metakeys
151 : *
152 : *
153 : *
154 : * @deprecated The flags below are deprecated and ::KEY_META should be
155 : * preferred. They remain some time, however, for compatibility:
156 : * - ::KEY_DIR \n
157 : * Define that the key is a directory rather than an ordinary key.
158 : * This means its executable bits in its mode are set.
159 : * But even without this option the key can have subkeys.
160 : * See keySetDir().
161 : * - ::KEY_OWNER \n
162 : * Next parameter is the owner. See keySetOwner().
163 : * - ::KEY_UID, ::KEY_GID \n
164 : * Next parameter is taken as the UID (uid_t) or GID (gid_t) that will
165 : * be defined on the key.
166 : * See keySetUID() and keySetGID().
167 : * - ::KEY_MODE \n
168 : * Next parameter is taken as mode permissions (int) to the key.
169 : * See keySetMode().
170 : * @snippet keyNew.c With Mode
171 : * - ::KEY_COMMENT \n
172 : * Next parameter is a comment. See keySetComment().
173 : * @snippet keyNew.c With Everything
174 : *
175 : *
176 : *
177 : * @param name a valid name to the key, or NULL to get a simple
178 : * initialized, but really empty, object
179 : * @see keyDel()
180 : * @return a pointer to a new allocated and initialized Key object.
181 : * @retval NULL on allocation error or if an invalid @p name was passed (see keySetName()).
182 : * @ingroup key
183 : *
184 : */
185 8277291 : Key * keyNew (const char * name, ...)
186 : {
187 : Key * k;
188 :
189 8277291 : if (!name)
190 : {
191 6260777 : k = elektraKeyMalloc ();
192 : }
193 : else
194 : {
195 : va_list va;
196 2016514 : va_start (va, name);
197 2016514 : k = keyVNew (name, va);
198 2016514 : va_end (va);
199 : }
200 :
201 8277291 : return k;
202 : }
203 :
204 :
205 : /**
206 : * @copydoc keyNew
207 : *
208 : * @pre caller must use va_start and va_end on va
209 : * @param va the variadic argument list
210 : */
211 2213958 : Key * keyVNew (const char * name, va_list va)
212 : {
213 2213958 : Key * key = elektraKeyMalloc ();
214 2213958 : if (!key) return 0;
215 2213958 : keyVInit (key, name, va);
216 2213958 : return key;
217 : }
218 :
219 : /**
220 : * Return a duplicate of a key.
221 : *
222 : * Memory will be allocated as needed for dynamic properties.
223 : *
224 : * The new key will not be member of any KeySet and
225 : * will start with a new reference counter at 0. A
226 : * subsequent keyDel() will delete the key.
227 : *
228 : * @code
229 : int f (const Key * source)
230 : {
231 : Key * dup = keyDup (source);
232 : // work with duplicate
233 : keyDel (dup);
234 : // everything related to dup is freed
235 : // and source is unchanged
236 : }
237 : * @endcode
238 : *
239 : * Like for a new key after keyNew() a subsequent ksAppend()
240 : * makes a KeySet to take care of the lifecycle of the key.
241 : *
242 : * @code
243 : int g (const Key * source, KeySet * ks)
244 : {
245 : Key * dup = keyDup (source);
246 : // work with duplicate
247 : ksAppendKey (ks, dup);
248 : // ksDel(ks) will also free the duplicate
249 : // source remains unchanged.
250 : }
251 : * @endcode
252 : *
253 : * Duplication of keys should be preferred to keyNew(),
254 : * because data like owner can be filled with a copy
255 : * of the key instead of asking the environment.
256 : * It can also be optimized in the checks, because the keyname
257 : * is known to be valid.
258 : *
259 : * @param source has to be an initialized source Key
260 : * @retval 0 failure or on NULL pointer
261 : * @return a fully copy of source on success
262 : * @see ksAppend(), keyDel(), keyNew()
263 : * @ingroup key
264 : */
265 1142735 : Key * keyDup (const Key * source)
266 : {
267 1142735 : Key * dest = 0;
268 :
269 1142735 : if (!source) return 0;
270 :
271 1142347 : dest = elektraKeyMalloc ();
272 1142347 : if (!dest) return 0;
273 :
274 : /* Copy the struct data */
275 1142347 : *dest = *source;
276 :
277 : /* get rid of properties bound to old key */
278 1142347 : dest->ksReference = 0;
279 1142347 : dest->flags = KEY_FLAG_SYNC;
280 :
281 : /* prepare to set dynamic properties */
282 1142347 : dest->key = dest->data.v = dest->meta = 0;
283 :
284 : /* copy dynamic properties */
285 1142347 : if (keyCopy (dest, source) == -1)
286 : {
287 0 : keyDel (dest);
288 0 : return 0;
289 : }
290 :
291 : return dest;
292 : }
293 :
294 :
295 : /**
296 : * Copy or Clear a key.
297 : *
298 : * Most often you may prefer keyDup() which allocates
299 : * a new key and returns a duplication of another key.
300 : *
301 : * But when you need to copy into an existing key, e.g.
302 : * because it was passed by a pointer in a function
303 : * you can do so:
304 : *
305 : * @snippet keyCopy.c Basic Usage
306 : *
307 : * The reference counter will not be changed for
308 : * both keys. Affiliation to keysets
309 : * are also not affected.
310 : *
311 : * The metadata will be duplicated for the destination
312 : * key. So it will not take much additional space, even
313 : * with lots of metadata.
314 : *
315 : * When you pass a NULL-pointer as source the
316 : * data of dest will be cleaned completely
317 : * (except reference counter, see keyClear()) and
318 : * you get a fresh dest key:
319 : *
320 : * @snippet keyCopy.c Clear
321 : *
322 : * If you want to copy everything, except e.g. the value
323 : * you can use keyCopy() too:
324 : *
325 : * @snippet keyCopy.c Copy Without Value
326 : *
327 : * Restrain from coping everything yourself, because it will lead to
328 : * wrong metadata and is not able to copy empty or cascading names:
329 : *
330 : * @snippet keyCopy.c Individual Copy
331 : *
332 : *
333 : * @param dest the key which will be written to
334 : * @param source the key which should be copied
335 : * or NULL to clean the destination key
336 : * @ingroup key
337 : * @retval -1 on failure when a NULL pointer
338 : * was passed for dest or a dynamic property could not
339 : * be written. The content will be unmodified then.
340 : * @retval 0 when dest was cleaned
341 : * @retval 1 when source was successfully copied
342 : * @see keyDup() to get a duplication of a key
343 : */
344 1142422 : int keyCopy (Key * dest, const Key * source)
345 : {
346 1142422 : if (!dest) return -1;
347 :
348 1142422 : if (test_bit (dest->flags, KEY_FLAG_RO_NAME) || test_bit (dest->flags, KEY_FLAG_RO_VALUE) ||
349 : test_bit (dest->flags, KEY_FLAG_RO_META))
350 : {
351 : return -1;
352 : }
353 :
354 1142420 : if (!source)
355 : {
356 12 : keyClear (dest);
357 12 : return 0;
358 : }
359 :
360 : // remember dynamic memory to be removed
361 1142408 : char * destKey = dest->key;
362 1142408 : void * destData = dest->data.c;
363 1142408 : KeySet * destMeta = dest->meta;
364 :
365 : // duplicate dynamic properties
366 1142408 : if (source->key)
367 : {
368 1121995 : dest->key = elektraStrNDup (source->key, source->keySize + source->keyUSize);
369 1121995 : if (!dest->key) goto memerror;
370 : }
371 : else
372 : {
373 20413 : dest->key = 0;
374 : }
375 :
376 1142408 : if (source->data.v)
377 : {
378 847880 : dest->data.v = elektraStrNDup (source->data.v, source->dataSize);
379 847880 : if (!dest->data.v) goto memerror;
380 : }
381 : else
382 : {
383 294528 : dest->data.v = 0;
384 : }
385 :
386 1142408 : if (source->meta)
387 : {
388 547263 : dest->meta = ksDup (source->meta);
389 547263 : if (!dest->meta) goto memerror;
390 : }
391 : else
392 : {
393 595145 : dest->meta = 0;
394 : }
395 :
396 : // successful, now do the irreversible stuff: we obviously modified dest
397 1142408 : set_bit (dest->flags, KEY_FLAG_SYNC);
398 :
399 : // copy sizes accordingly
400 1142408 : dest->keySize = source->keySize;
401 1142408 : dest->keyUSize = source->keyUSize;
402 1142408 : dest->dataSize = source->dataSize;
403 :
404 : // free old resources of destination
405 1142408 : if (!test_bit (dest->flags, KEY_FLAG_MMAP_KEY)) elektraFree (destKey);
406 1142408 : if (!test_bit (dest->flags, KEY_FLAG_MMAP_DATA)) elektraFree (destData);
407 1142408 : ksDel (destMeta);
408 :
409 1142408 : return 1;
410 :
411 : memerror:
412 0 : elektraFree (dest->key);
413 0 : elektraFree (dest->data.v);
414 0 : ksDel (dest->meta);
415 :
416 0 : dest->key = destKey;
417 0 : dest->data.v = destData;
418 0 : dest->meta = destMeta;
419 0 : return -1;
420 : }
421 :
422 :
423 : /**
424 : * A destructor for Key objects.
425 : *
426 : * Every key created by keyNew() must be
427 : * deleted with keyDel().
428 : *
429 : * It is safe to delete keys which are
430 : * in a keyset, the number of references
431 : * will be returned then.
432 : *
433 : * It is save to delete a nullpointer,
434 : * -1 will be returned then.
435 : *
436 : * It is also save to delete a multiple
437 : * referenced key, nothing will happen
438 : * then and the reference counter will
439 : * be returned.
440 : *
441 : * @param key the key object to delete
442 : * @see keyNew(), keyIncRef(), keyGetRef()
443 : * @return the value of the reference counter
444 : * if the key is within keyset(s)
445 : * @retval 0 when the key was freed
446 : * @retval -1 on null pointers
447 : * @ingroup key
448 : *
449 : */
450 21607457 : int keyDel (Key * key)
451 : {
452 : int rc;
453 :
454 21607457 : if (!key) return -1;
455 :
456 21501366 : if (key->ksReference > 0)
457 : {
458 11883201 : return key->ksReference;
459 : }
460 :
461 9618165 : int keyInMmap = test_bit (key->flags, KEY_FLAG_MMAP_STRUCT);
462 :
463 9618165 : rc = keyClear (key);
464 :
465 9618165 : if (!keyInMmap)
466 : {
467 9616727 : elektraFree (key);
468 : }
469 :
470 : return rc;
471 : }
472 :
473 : /**
474 : * Key Object Cleaner.
475 : *
476 : * Will reset all internal data.
477 : *
478 : * After this call you will receive a fresh
479 : * key.
480 : *
481 : * The reference counter will stay unmodified.
482 : *
483 : * @note that you might also clear() all aliases
484 : * with this operation.
485 : *
486 : * @code
487 : int f (Key *k)
488 : {
489 : keyClear (k);
490 : // you have a fresh key k here
491 : keySetString (k, "value");
492 : // the caller will get an empty key k with an value
493 : }
494 : * @endcode
495 : *
496 : * @retval returns 0 on success
497 : * @retval -1 on null pointer
498 : *
499 : * @param key the key object to work with
500 : * @ingroup key
501 : */
502 9618201 : int keyClear (Key * key)
503 : {
504 9618201 : if (!key)
505 : {
506 : return -1;
507 : }
508 :
509 9618201 : size_t ref = 0;
510 :
511 9618201 : ref = key->ksReference;
512 :
513 9618201 : int keyStructInMmap = test_bit (key->flags, KEY_FLAG_MMAP_STRUCT);
514 :
515 9618201 : if (key->key && !test_bit (key->flags, KEY_FLAG_MMAP_KEY)) elektraFree (key->key);
516 9618201 : if (key->data.v && !test_bit (key->flags, KEY_FLAG_MMAP_DATA)) elektraFree (key->data.v);
517 9618201 : if (key->meta) ksDel (key->meta);
518 :
519 9618201 : keyInit (key);
520 :
521 9618201 : if (keyStructInMmap) key->flags |= KEY_FLAG_MMAP_STRUCT;
522 :
523 : /* Set reference properties */
524 9618201 : key->ksReference = ref;
525 :
526 9618201 : return 0;
527 : }
528 :
529 :
530 : /**
531 : * Increment the viability of a key object.
532 : *
533 : * This function is intended for applications
534 : * using their own reference counter for
535 : * key objects. With it you can increment
536 : * the reference and thus avoid destruction
537 : * of the object in a subsequent keyDel().
538 : *
539 : * The reference counter can't be incremented
540 : * once it reached SSIZE_MAX. In that situation
541 : * nothing will happen and SSIZE_MAX will be
542 : * returned.
543 : *
544 : * @note keyDup() will reset the references for dupped key.
545 : *
546 : * @return the value of the new reference counter
547 : * @retval -1 on null pointer
548 : * @retval SSIZE_MAX when maximum exceeded
549 : * @param key the key object to work with
550 : * @see keyGetRef() for longer explanation, keyDecRef(), keyDel()
551 : * @ingroup key
552 : */
553 15665930 : ssize_t keyIncRef (Key * key)
554 : {
555 15665930 : if (!key) return -1;
556 :
557 15323410 : if (key->ksReference < SSIZE_MAX)
558 15323410 : return ++key->ksReference;
559 : else
560 : return SSIZE_MAX;
561 : }
562 :
563 :
564 : /**
565 : * Decrement the viability of a key object.
566 : *
567 : * The references will be decremented for ksPop() or successful calls
568 : * of ksLookup() with the option KDB_O_POP.
569 : * It will also be decremented with an following keyDel() in
570 : * the case that an old key is replaced with another key with
571 : * the same name.
572 : *
573 : * The reference counter can't be decremented
574 : * once it reached 0. In that situation
575 : * nothing will happen and 0 will be
576 : * returned.
577 : *
578 : * @note keyDup() will reset the references for dupped key.
579 : *
580 : * @return the value of the new reference counter
581 : * @retval -1 on null pointer
582 : * @retval 0 when the key is ready to be freed
583 : * @param key the key object to work with
584 : * @see keyGetRef() for longer explanation, keyDel(), keyIncRef()
585 : * @ingroup key
586 : */
587 15535355 : ssize_t keyDecRef (Key * key)
588 : {
589 15535355 : if (!key) return -1;
590 :
591 15519445 : if (key->ksReference > 0)
592 15324282 : return --key->ksReference;
593 : else
594 : return 0;
595 : }
596 :
597 :
598 : /**
599 : * Return how many references the key has.
600 : *
601 : * The reference counting is the essential property of keys to make sure
602 : * that they can be put safely into data structures. E.g. if you put
603 : * a Key into a KeySet:
604 : *
605 : * @snippet keyNew.c Ref in KeySet
606 : *
607 : * You can even add the key to more KeySets:
608 : *
609 : * @snippet keyNew.c Ref in multiple KeySets
610 : *
611 : * If you increment only by one with keyIncRef() the same as said above
612 : * is valid:
613 : *
614 : * @snippet keyNew.c Ref
615 : *
616 : * or use keyIncRef() more than once:
617 : *
618 : * @snippet keyNew.c Multi Ref
619 : *
620 : * The key won't be deleted by a keyDel() as long refcounter is not 0.
621 : *
622 : * The references will be incremented on successful calls to
623 : * ksAppendKey() or ksAppend().
624 : *
625 : * @note keyDup() will reset the references for dupped key.
626 : *
627 : * For your own applications you can use
628 : * keyIncRef() and keyDecRef() for reference
629 : * counting, too.
630 : *
631 : * @param key the key object to work with
632 : * @return the number of references
633 : * @retval -1 on null pointer
634 : * @see keyIncRef() and keyDecRef()
635 : * @ingroup key
636 : **/
637 385 : ssize_t keyGetRef (const Key * key)
638 : {
639 385 : if (!key) return -1;
640 :
641 385 : return key->ksReference;
642 : }
|