Git init
[pkgs/e/elektra.git] / src / libelektra / key.c
1  /***************************************************************************
2                           key.c  -  Methods for Key manipulation
3                              -------------------
4     begin                : Mon Dec 29 2003
5     copyright            : (C) 2003 by Avi Alkalay
6     email                : avi@unix.sh
7  ***************************************************************************/
8
9 /***************************************************************************
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the BSD License (revised).                      *
13  *                                                                         *
14  ***************************************************************************/
15
16
17 /**
18  * @defgroup key Key :: Basic Methods
19  * @brief Key construction and initialization methods.
20  *
21  * To use them:
22  * @code
23 #include <kdb.h>
24  * @endcode
25  *
26  * A Key is the essential class that encapsulates key @link keyname name @endlink,
27  * @link keyvalue value @endlink and @link keymeta metainfo @endlink.
28  * Key properties are:
29  * - @link keyname Key name @endlink
30  * - @link keyvalue Key value @endlink
31  * - @link keySetType() Data type @endlink
32  * - @link keyGetComment() Key comment @endlink
33  * - @link keyGetOwner() Key owner @endlink
34  * - @link keymeta UID, GID and filesystem-like mode permissions @endlink
35  * - @link keymeta Mode, change and modification times @endlink
36  *
37  * Described here the methods to allocate and free the key.
38  *
39  */
40
41
42
43 #ifdef HAVE_CONFIG_H
44 #include "config.h"
45 #endif
46
47 #if DEBUG && HAVE_STDIO_H
48 #include <stdio.h>
49 #endif
50
51 #ifdef HAVE_STDARG_H
52 #include <stdarg.h>
53 #endif
54
55 #ifdef HAVE_STRING_H
56 #include <string.h>
57 #endif
58
59 #ifdef HAVE_STDLIB_H
60 #include <stdlib.h>
61 #endif
62
63 #include "kdb.h"
64 #include "kdbprivate.h"
65
66
67 /**
68  * A practical way to fully create a Key object in one step.
69  *
70  * This function tries to mimic the C++ way for constructors.
71  *
72  * To just get a key object, simple do:
73  * @code
74 Key *k = keyNew(0);
75 // work with it
76 keyDel (k);
77  * @endcode
78  *
79  * If you want the key object to contain a name, value, comment and other
80  * meta info read on.
81  *
82  * @note When you already have a key with similar properties its
83  * easier and cheaper to keyDup() the key.
84  *
85  * Due to ABI compatibility, the @p Key structure is not defined in kdb.h,
86  * only declared. So you can only declare @p pointers to @p Keys in your
87  * program, and allocate and free memory for them with keyNew()
88  * and keyDel() respectively.
89  * See http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html#AEN135
90  *
91  * You can call it in many different ways depending on the attribute tags you
92  * pass as parameters. Tags are represented as the #keyswitch_t values,
93  * and tell keyNew() which Key attribute comes next.
94  *
95  * The simplest and minimum way to use it is with no tags, only a key name:
96  * @code
97 Key *nullKey,*emptyNamedKey;
98
99 // Create a key that has no name, is completely empty, but is initialized
100 nullKey=keyNew(0);
101 keyDel (nullKey);
102
103 // Is the same as above
104 nullKey=keyNew("", KEY_END);
105 keyDel (nullKey);
106
107 // Create and initialize a key with a name and nothing else
108 emptyNamedKey=keyNew("user/some/example",KEY_END);
109 keyDel (emptyNamedKey);
110  * @endcode
111  *
112  * keyNew() allocates memory for a key object and cleans everything up. After
113  * that, it processes the given argument list.
114  *
115  * The Key attribute tags are the following:
116  * - keyswitch_t::KEY_TYPE \n
117  *   Next parameter is a type of the value. Default assumed is KEY_TYPE_UNDEFINED.
118  *   Set this attribute so that a subsequent KEY_VALUE can toggle to keySetString()
119  *   or keySetBinary() regarding to keyIsString() or keyIsBinary().
120  *   If you don't use KEY_TYPE but a KEY_VALUE follows afterwards, KEY_TYPE_STRING
121  *   will be used.
122  * - keyswitch_t::KEY_SIZE \n
123  *   Define a maximum length of the value. This is especially useful for setting
124  *   a binary key. So make sure you use that before you KEY_VALUE for
125  *   binary keys.
126  * - keyswitch_t::KEY_VALUE \n
127  *   Next parameter is a pointer to the value that will be set to the key
128  *   If no keyswitch_t::KEY_TYPE was used before,
129  *   keyswitch_t::KEY_TYPE_STRING is assumed. If KEY_TYPE was previously
130  *   passed with a KEY_TYPE_BINARY,
131  *   you should have passed KEY_SIZE before! Otherwise it will be cut of
132  *   with first \\0 in string!
133  * - keyswitch_t::KEY_UID, @p keyswitch_t::KEY_GID \n
134  *   Next parameter is taken as the UID (uid_t) or GID (gid_t) that will
135  *   be defined on the key. See keySetUID() and keySetGID().
136  * - keyswitch_t::KEY_MODE \n
137  *   Next parameter is taken as mode permissions (mode_t) to the key.
138  *   See keySetMode().
139  * - keyswitch_t::KEY_DIR \n
140  *   Define that the key is a directory rather than a ordinary key.
141  *   This means its executable bits in its mode are set. This option
142  *   allows the key to have subkeys.
143  *   See keySetDir().
144  * - keyswitch_t::KEY_OWNER \n
145  *   Next parameter is the owner. See keySetOwner().
146  * - keyswitch_t::KEY_COMMENT \n
147  *   Next parameter is a comment. See keySetComment().
148  * - keyswitch_t::KEY_REMOVE \n
149  *   Mark the key to be removed instead of set it.
150  *   See keyRemove().
151  * - keyswitch_t::KEY_STAT \n
152  *   Mark the key to be stated instead of get it.
153  *   See keyStat().
154  * - keyswitch_t::KEY_END \n
155  *   Must be the last parameter passed to keyNew(). It is always
156  *   required, unless the @p keyName is 0.
157  *
158  * @par Example:
159  * @code
160 KeySet *ks=ksNew(0);
161
162 ksAppendKey(ks,keyNew(0));       // an empty key
163
164 ksAppendKey(ks,keyNew("user/sw",              // the name of the key
165         KEY_END));                      // no more args
166
167 ksAppendKey(ks,keyNew("user/tmp/ex1",
168         KEY_VALUE,"some data",          // set a string value
169         KEY_END));                      // end of args
170
171 ksAppendKey(ks,keyNew("user/tmp/ex2",
172         KEY_VALUE,"some data",          // with a simple value
173         KEY_MODE,0777,                  // permissions
174         KEY_END));                      // end of args
175
176 ksAppendKey(ks,keyNew("user/tmp/ex4",
177         KEY_TYPE,KEY_TYPE_BINARY,       // key type
178         KEY_SIZE,7,                     // assume binary length 7
179         KEY_VALUE,"some data",          // value that will be truncated in 7 bytes
180         KEY_COMMENT,"value is truncated",
181         KEY_OWNER,"root",               // owner (not uid) is root
182         KEY_UID,0,                      // root uid
183         KEY_END));                      // end of args
184
185 ksAppendKey(ks,keyNew("user/tmp/ex5",
186         KEY_TYPE,
187                 KEY_TYPE_DIR | KEY_TYPE_BINARY,// dir key with a binary value
188         KEY_SIZE,7,
189         KEY_VALUE,"some data",          // value that will be truncated in 7 bytes
190         KEY_COMMENT,"value is truncated",
191         KEY_OWNER,"root",               // owner (not uid) is root
192         KEY_UID,0,                      // root uid
193         KEY_END));                      // end of args
194
195 ksDel(ks);
196  * @endcode
197  *
198  * The reference counter (see keyGetRef()) will be initialized
199  * with 0, that means a subsequent call of keyDel() will delete
200  * the key. If you append the key to a keyset the reference counter
201  * will be incremented by one (see keyInc()) and the key can't be
202  * be deleted by a keyDel().
203  *
204  *@code
205 Key *k = keyNew(0); // ref counter 0
206 ksAppendKey(ks, k); // ref counter of key 1
207 ksDel(ks); // key will be deleted with keyset
208  *@endcode
209  *
210  * If you increment only by one with keyInc() the same as said above
211  * is valid:
212  *
213  *@code
214 Key *k = keyNew(0); // ref counter 0
215 keyIncRef(k); // ref counter of key 1
216 keyDel(k);    // has no effect
217 keyDecRef(k); // ref counter back to 0
218 keyDel(k);    // key is now deleted
219  *@endcode
220  *
221  * If you add the key to more keySets:
222  *
223  *@code
224 Key *k = keyNew(0); // ref counter 0
225 ksAppendKey(ks1, k); // ref counter of key 1
226 ksAppendKey(ks2, k); // ref counter of key 2
227 ksDel(ks1); // ref counter of key 1
228 ksDel(ks2); // k is now deleted
229  *@endcode
230  *
231  * or use keyInc() more than once:
232  *
233  *@code
234 Key *k = keyNew(0); // ref counter 0
235 keyIncRef(k); // ref counter of key 1
236 keyDel (k);   // has no effect
237 keyIncRef(k); // ref counter of key 2
238 keyDel (k);   // has no effect
239 keyDecRef(k); // ref counter of key 1
240 keyDel (k);   // has no effect
241 keyDecRef(k); // ref counter is now 0
242 keyDel (k); // k is now deleted
243  *@endcode
244  *
245  * they key won't be deleted by a keyDel() as long refcounter is not 0.
246  *
247  * The key's sync bit will always be set for any call, except:
248  * @code
249 Key *k = keyNew(0);
250 // keyNeedSync() will be false
251  * @endcode
252  *
253  * @param keyName a valid name to the key, or NULL to get a simple
254  *      initialized, but really empty, object 
255  * @see keyDel()
256  * @return a pointer to a new allocated and initialized Key object,
257  *      or NULL if an invalid @p keyName was passed (see keySetName()).
258  * @ingroup key
259  * 
260  */
261 Key *keyNew(const char *keyName, ...) {
262         Key * k;
263         va_list va;
264
265         if (keyName) va_start(va,keyName);
266         k = keyVNew (keyName, va);
267         if (keyName) va_end (va);
268
269         return k;
270 }
271
272
273 Key *keyVNew (const char *keyName, va_list va)
274 {
275         Key *key=0;
276         type_t type=0;
277         keyswitch_t action=0;
278         void * value=0;
279         ssize_t valueSize=-1;
280
281         key=(Key *)malloc(sizeof(Key));
282         if (!key) return 0;
283         keyInit(key);
284
285         if (keyName) {
286                 keySetName(key,keyName);
287
288                 action=va_arg(va, keyswitch_t);
289                 while (action) {
290                         switch (action) {
291                                 case KEY_TYPE:
292                                         type = (type_t) va_arg(va, type_t);
293                                         keySetType(key, type);
294                                         break;
295                                 case KEY_SIZE:
296                                         valueSize=va_arg(va, size_t);
297                                         break;
298                                 case KEY_VALUE:
299                                         value = va_arg(va, void *);
300                                         if (valueSize>=0 && keyIsBinary(key))
301                                         {
302                                                 keySetBinary(key,value, valueSize);
303                                         } else if (keyIsBinary(key)) {
304                                                 valueSize = (ssize_t) kdbiStrLen (value);
305                                                 keySetBinary(key,value, valueSize);
306                                         } else {
307                                                 keySetString(key,value);
308                                         }
309                                         break;
310                                 case KEY_UID:
311                                         keySetUID(key,va_arg(va,uid_t));
312                                         break;
313                                 case KEY_GID:
314                                         keySetGID(key,va_arg(va,gid_t));
315                                         break;
316                                 case KEY_MODE:
317                                         keySetMode(key,va_arg(va, mode_t));
318                                         break;
319                                 case KEY_OWNER:
320                                         keySetOwner(key,va_arg(va,char *));
321                                         break;
322                                 case KEY_COMMENT:
323                                         keySetComment(key,va_arg(va,char *));
324                                         break;
325                                 case KEY_REMOVE:
326                                         keyRemove(key);
327                                         break;
328                                 case KEY_STAT:
329                                         keyStat(key);
330                                         break;
331                                 case KEY_DIR:
332                                         keySetDir(key);
333                                         break;
334                                 default:
335 #if DEBUG
336                                         fprintf (stderr, "Unknown option in keyNew %ld\n", (long int)action);
337 #endif
338                                         break;
339                         }
340                         action=va_arg(va, keyswitch_t);
341                 }
342         }
343         return key;
344 }
345
346 /**
347  * Return a duplicate of a key.
348  *
349  * Memory will be allocated as needed for dynamic properties.
350  *
351  * The new key will not be member of any KeySet and
352  * will start with a new reference counter at 0. A
353  * subsequent keyDel() will delete the key.
354  *
355  * @code
356 int f (const Key * source)
357 {
358         Key * dup = keyDup (source);
359         // work with duplicate
360         keyDel (dup);
361         // everything related to dup is freed
362         // and source is unchanged
363 }
364  * @endcode
365  *
366  * Like for a new key after keyNew() a subsequent ksAppend()
367  * makes a KeySet to take care of the lifecycle of the key.
368  *
369  * @code
370 int g (const Key * source, KeySet * ks)
371 {
372         Key * dup = keyDup (source);
373         // work with duplicate
374         ksAppendKey (ks, dup);
375         // ksDel(ks) will also free the duplicate
376         // source remains unchanged.
377 }
378  * @endcode
379  *
380  * Duplication of keys should be preferred to keyNew(),
381  * because data like owner can be filled with a copy
382  * of the key instead of asking the environment.
383  * It can also be optimized in the checks, because the keyname
384  * is known to be valid.
385  *
386  * @param source has to be an initializised source Key
387  * @return 0 failure or on NULL pointer
388  * @return a fully copy of source on success
389  * @see ksAppend(), keyDel()
390  * @see keyClear(), keyNew()
391  * @ingroup key
392  */
393 Key* keyDup(const Key *source)
394 {
395         Key * dest = 0;
396
397         if (!source) return 0;
398
399         dest = (Key *)malloc(sizeof(Key));
400         if (!dest) return 0;
401         keyInit(dest);
402
403         /* Copy the struct data, including the "next" pointer */
404         *dest=*source;
405
406         /* prepare to set dynamic properties */
407         dest->key=
408         dest->comment=
409         dest->owner=
410         dest->data=0;
411
412         dest->ksReference = 0;
413
414         if (source->key && keySetName(dest,source->key) == -1) goto memerror;
415         if (source->comment && keySetComment(dest,source->comment) == -1) goto memerror;
416         if (source->owner && keySetOwner(dest,source->owner) == -1) goto memerror;
417         if (source->data && keySetRaw(dest,source->data,source->dataSize) == -1) goto memerror;
418         
419         return dest;
420 memerror:
421         keyDel (dest);
422         return 0;
423 }
424
425
426
427
428 /**
429  * Copy or Clear a key.
430  *
431  * Most often you may prefer keyDup() which allocates
432  * a new key and returns a duplication of another key.
433  *
434  * But when you need to copy into an existing key, e.g.
435  * because it was passed by a pointer in a function
436  * you can do so:
437  *
438  * @code
439 int h (Key *k)
440 {
441         // receive key c
442         keyCopy (k, c);
443         // the caller will see the changed key k
444 }
445  * @endcode
446  *
447  * The reference counter will not change for
448  * the destination key. Affiliation to keysets
449  * are also not affected.
450  *
451  * When you pass a NULL-pointer as source the
452  * data of dest will be cleaned completely and
453  * you get a fresh dest key.
454  *
455  * @code
456 int g (Key *k)
457 {
458         keyCopy (k, 0);
459         // k is now an empty and fresh key
460 }
461  * @endcode
462  *
463  * @param dest the key which will be written to
464  * @param source the key which should be copied
465  *     or NULL to clean the destination key
466  * @ingroup key
467  * @return -1 on failure when a NULL pointer
468  *     was passed for dest or a dynamic property could not
469  *     be written.
470  * @return 0 when dest was cleaned
471  * @return 1 when source was successfully copied
472  * @see keyDup() to get a duplication of a key
473  */
474 int keyCopy (Key *dest, const Key *source)
475 {
476         size_t destref = 0;
477
478         if (!dest) return -1;
479         destref = dest->ksReference;
480
481         /* free everything in dest */
482         keySetName (dest, 0);
483         keySetComment (dest,0);
484         keySetOwner (dest, 0);
485         keySetRaw (dest, 0, 0);
486
487         keyClear (dest);
488
489         if (!source) return 0;
490
491         /* copy all data of structure */
492         *dest=*source;
493
494         /* Set reference properties */
495         dest->ksReference = destref;
496
497         /* prepare to set dynamic properties */
498         dest->key=
499         dest->comment=
500         dest->owner=
501         dest->data=0;
502
503         if (keySetName(dest,source->key) == -1) return -1;
504         if (keySetComment(dest,source->comment) == -1) return -1;
505         if (keySetOwner(dest,source->owner) == -1) return -1;
506         if (keySetRaw(dest,source->data,source->dataSize) == -1) return -1;
507
508         return 1;
509 }
510
511
512
513
514
515 /**
516  * A destructor for Key objects.
517  *
518  * Every key created by keyNew() must be
519  * deleted with keyDel().
520  *
521  * It is save to delete keys which are
522  * in a keyset, the number of references
523  * will be returned then.
524  *
525  * It is save to delete a nullpointer,
526  * -1 will be returned then.
527  *
528  * @param key the key object to delete
529  * @see keyNew(), keyInc(), keyGetRef()
530  * @return the value of the reference counter
531  *         if the key is within keyset(s)
532  * @return 0 when the key was freed
533  * @return -1 on null pointers
534  * @ingroup key
535  *
536  */
537 int keyDel(Key *key) {
538         int rc;
539
540         if (!key) return -1;
541
542         if (key->ksReference > 0)
543         {
544                 return key->ksReference;
545         }
546
547         rc=keyClear(key);
548         kdbiFree (key);
549
550         return rc;
551 }
552
553 /*
554  * Key Object Cleaner.
555  *
556  * Will reset all internal data.
557  *
558  * After this call you will receive a fresh
559  * key.
560  *
561  * @code
562 int f (Key *k)
563 {
564         keyClear (k);
565         // you have a fresh key k here
566         keySetString (k, "value");
567         // the caller will get an empty key k with an value
568 }
569  * @endcode
570  *
571  * @param key the key object to work with
572  * @ingroup key
573  */
574 int keyClear(Key *key)
575 {
576         if (key->key) free(key->key);
577         if (key->data) free(key->data);
578         if (key->comment) free(key->comment);
579         if (key->owner) free(key->owner);
580
581         memset(key,0,sizeof(Key));
582         keyInit (key);
583
584         return 0;
585 }
586
587
588
589 /**
590  * Increment the viability of a key object.
591  *
592  * This function is intended for applications
593  * using their own reference counter for
594  * key objects. With it you can increment
595  * the reference and thus avoid destruction
596  * of the object in a subsequent keyDel().
597  *
598  * @code
599 Key *k;
600 keyInc (k);
601 function_that_keyDec(k);
602 // work with k
603 keyDel (k); // now really free it
604  * @endcode
605  *
606  * The reference counter can't be incremented
607  * once it reached SSIZE_MAX. In that situation
608  * nothing will happen and SSIZE_MAX will be
609  * returned.
610  *
611  * @return the value of the new reference counter
612  * @return -1 on null pointer
613  * @return SSIZE_MAX when maximum exceeded
614  * @param key the key object to work with
615  * @see keyGetRef(), keyDecRef(), keyDel()
616  * @ingroup key
617  */
618 ssize_t keyIncRef(Key *key)
619 {
620         if (!key) return -1;
621
622         if (key->ksReference < SSIZE_MAX) return ++ key->ksReference;
623         else return SSIZE_MAX;
624 }
625
626
627
628 /**
629  * Decrement the viability of a key object.
630  *
631  * The reference counter can't be decremented
632  * once it reached 0. In that situation
633  * nothing will happen and 0 will be
634  * returned.
635  *
636  * @return the value of the new reference counter
637  * @return -1 on null pointer
638  * @return 0 when the key is ready to be freed
639  * @param key the key object to work with
640  * @see keyGetRef(), keyDel(), keyIncRef()
641  * @ingroup key
642  */
643 ssize_t keyDecRef(Key *key)
644 {
645         if (!key) return -1;
646
647         if (key->ksReference>0) return -- key->ksReference;
648         else return 0;
649 }
650
651
652
653
654 /**
655  * Return how many references the key has.
656  *
657  * The references will be incremented when ksAppendKey()
658  * or ksAppend() uses the key and will be decremented when
659  * ksPop() is used.
660  *
661  * keyDup() will reset the references for dupped
662  * key.
663  *
664  * For your own applications you can use
665  * keyIncRef() and keyDelRef() for reference
666  * counting. Keys with zero references
667  * will be deleted when using keyDel().
668  *
669  * @param key the key object to work with
670  * @return the number of references
671  * @return -1 on null pointer
672  * @see keyIncRef() and keyDecRef()
673  * @ingroup key
674  **/
675 ssize_t keyGetRef(const Key *key)
676 {
677         if (!key) return -1;
678
679         return key->ksReference;
680 }
681