Elektra  0.8.21
Functions
Name Manipulation Methods

Methods to do various operations on Key names. More...

Collaboration diagram for Name Manipulation Methods:

Functions

const char * keyName (const Key *key)
 Returns a pointer to the abbreviated real internal key name. More...
 
ssize_t keyGetNameSize (const Key *key)
 Bytes needed to store the key name without owner. More...
 
const void * keyUnescapedName (const Key *key)
 Returns a keyname which is null separated and does not use backslash for escaping. More...
 
ssize_t keyGetUnescapedNameSize (const Key *key)
 return size of unescaped name with embedded and terminating null characters More...
 
ssize_t keyGetName (const Key *key, char *returnedName, size_t maxSize)
 Get abbreviated key name (without owner name). More...
 
ssize_t keySetName (Key *key, const char *newName)
 Set a new name to a key. More...
 
ssize_t keyGetFullNameSize (const Key *key)
 Bytes needed to store the key name including user domain and ending NULL. More...
 
ssize_t keyGetFullName (const Key *key, char *returnedName, size_t maxSize)
 Get key full name, including the user domain name. More...
 
const char * keyBaseName (const Key *key)
 Returns a pointer to the internal unescaped key name where the basename starts. More...
 
ssize_t keyGetBaseNameSize (const Key *key)
 Calculates number of bytes needed to store basename of key. More...
 
ssize_t keyGetBaseName (const Key *key, char *returned, size_t maxSize)
 Calculate the basename of a key name and put it in returned finalizing the string with NULL. More...
 
ssize_t keyAddBaseName (Key *key, const char *baseName)
 Adds baseName (that will be escaped) to the current key name. More...
 
ssize_t keyAddName (Key *key, const char *newName)
 Add an already escaped name to the keyname. More...
 
ssize_t keySetBaseName (Key *key, const char *baseName)
 Sets baseName as the new basename for key. More...
 
elektraNamespace keyGetNamespace (const Key *key)
 For currently valid namespaces see elektraNamespace. More...
 

Detailed Description

Methods to do various operations on Key names.

To use them:

#include <kdb.h>

These functions make it easier for C programmers to work with key names.

Terminology of Key Names
  • A key name (see keySetName() and keyName()) defines the place of a key within the key database. To be unique, it is always absolute and canonical.
  • Key names are composed out of many key name parts split by a separator. These key name parts do not contain an unescaped separator.
  • A key base name (see keySetBaseName() and keyAddBaseName()) is the last part of the key name.
  • A C-String is a null terminated sequence of characters. So \0 (null-character) must not occur within a C-String.
Namespaces
A namespace denotes the place the key comes from:

Function Documentation

◆ keyAddBaseName()

ssize_t keyAddBaseName ( Key *  key,
const char *  baseName 
)

Adds baseName (that will be escaped) to the current key name.

A new baseName will be added, no other part of the key name will be affected.

Assumes that key is a directory and will append baseName to it. The function adds the path separator for concatenating.

So if key has name "system/dir1/dir2" and this method is called with baseName "mykey", the resulting key will have the name "system/dir1/dir2/mykey".

When baseName is 0 nothing will happen and the size of the name is returned.

The escaping rules apply as in above .

A simple example is:

E.g. if you add . it will be escaped:

keySetName (k, "system/valid");
succeed_if (keyAddBaseName (k, ".") >= 0, "could not add a base name");
succeed_if_same_string (keyName (k), "system/valid/\\.");
succeed_if_same_string (keyBaseName (k), ".");
See also
keySetBaseName() to set a base name
keySetName() to set a new name.
Parameters
keythe key object to work with
baseNamethe string to append to the name
Returns
the size in bytes of the new key name including the ending NULL
Return values
-1if the key had no name
-1on NULL pointers
-1if key was inserted to a keyset before

◆ keyAddName()

ssize_t keyAddName ( Key *  key,
const char *  newName 
)

Add an already escaped name to the keyname.

The same way as in keySetName() this method finds the canonical pathname:

  • it will ignore /./
  • it will remove a level when /../ is used
  • it will remove multiple slashes ////

For example:

Key * k = keyNew ("user/x/r", KEY_END);
keyAddName (k, "../y/a//././z");
assert (!strcmp (keyName (k), "user/x/y/a/z"));
keyDel (k);

Unlike keySetName() it adds relative to the previous name and cannot change the namespace of a key. For example:

Key * n = keyNew ("user/away", KEY_END);
keyAddName (n, "../../../new/name");
assert (!strcmp (keyName (n), "user/new/name"));
keyDel (n);

The passed name needs to be valid according the key name rules . It is not allowed to:

  • be empty
  • end with unequal number of \
Parameters
keythe key where a name should be added
newNamethe new name to append
Since
0.8.11
Return values
sizeof the new key
-1if key is a null pointer or did not have a valid name before
-1if newName is not a valid escaped name
-1on allocation errors
-1if key was inserted to a keyset before
0if nothing was done because newName had only slashes, is too short, is empty or is null

◆ keyBaseName()

const char* keyBaseName ( const Key *  key)

Returns a pointer to the internal unescaped key name where the basename starts.

This is a much more efficient version of keyGetBaseName() and you should use it if you are responsible enough to not mess up things. The name might change or even point to a wrong place after a keySetName(). So make sure to copy the memory before the name changes.

keyBaseName() returns "" when there is no keyBaseName. The reason is

keySetName (k, "");
succeed_if_same_string (keyBaseName (k), "");
keySetName (k, "user");
succeed_if_same_string (keyBaseName (k), "");

And there is also support for really empty basenames:

keySetName (k, "system/valid");
succeed_if (keyAddBaseName (k, "") >= 0, "could not add a base name");
succeed_if_same_string (keyName (k), "system/valid/%");
succeed_if_same_string (keyBaseName (k), "");
Note
You must never use the pointer returned by keyBaseName() method to change the name, but you should use keySetBaseName() instead.
Do not assume that keyBaseName() points to the same region as keyName() does.
Parameters
keythe object to obtain the basename from
Returns
a pointer to the basename
Return values
""when the key has no (base)name
0on NULL pointer
See also
keyGetBaseName(), keyGetBaseNameSize()
keyName() to get a pointer to the name
keyOwner() to get a pointer to the owner

◆ keyGetBaseName()

ssize_t keyGetBaseName ( const Key *  key,
char *  returned,
size_t  maxSize 
)

Calculate the basename of a key name and put it in returned finalizing the string with NULL.

Some examples:

  • basename of system/some/keyname is keyname
  • basename of "user/tmp/some key" is "some key"
Parameters
keythe key to extract basename from
returneda pre-allocated buffer to store the basename
maxSizesize of the returned buffer
Returns
number of bytes copied to returned
Return values
1on empty name
-1on NULL pointers
-1when maxSize is 0 or larger than SSIZE_MAX
See also
keyBaseName(), keyGetBaseNameSize()
keyName(), keyGetName(), keySetName()

◆ keyGetBaseNameSize()

ssize_t keyGetBaseNameSize ( const Key *  key)

Calculates number of bytes needed to store basename of key.

Key names that have only root names (e.g. "system" or "user" or "user:domain" ) does not have basenames, thus the function will return 1 bytes to store "".

Basenames are denoted as:

  • system/some/thing/basename -> basename
  • user:domain/some/thing/base\/name > base\/name
Parameters
keythe key object to work with
Returns
size in bytes of key's basename including ending NULL
See also
keyBaseName(), keyGetBaseName()
keyName(), keyGetName(), keySetName()

◆ keyGetFullName()

ssize_t keyGetFullName ( const Key *  key,
char *  returnedName,
size_t  maxSize 
)

Get key full name, including the user domain name.

Returns
number of bytes written
Return values
1on empty name
-1on NULL pointers
-1if maxSize is 0 or larger than SSIZE_MAX
Parameters
keythe key object
returnedNamepre-allocated memory to write the key name
maxSizemaximum number of bytes that will fit in returnedName, including the final NULL

◆ keyGetFullNameSize()

ssize_t keyGetFullNameSize ( const Key *  key)

Bytes needed to store the key name including user domain and ending NULL.

Parameters
keythe key object to work with
Returns
number of bytes needed to store key name including user domain
Return values
1on empty name
-1on NULL pointer
See also
keyGetFullName(), keyGetNameSize()

◆ keyGetName()

ssize_t keyGetName ( const Key *  key,
char *  returnedName,
size_t  maxSize 
)

Get abbreviated key name (without owner name).

When there is not enough space to write the name, nothing will be written and -1 will be returned.

maxSize is limited to SSIZE_MAX. When this value is exceeded -1 will be returned. The reason for that is that any value higher is just a negative return value passed by accident. Of course elektraMalloc is not as failure tolerant and will try to allocate.

char *getBack = elektraMalloc (keyGetNameSize(key));
keyGetName(key, getBack, keyGetNameSize(key));
Returns
number of bytes written to returnedName
Return values
1when only a null was written
-1when keyname is longer then maxSize or 0 or any NULL pointer
Parameters
keythe key object to work with
returnedNamepre-allocated memory to write the key name
maxSizemaximum number of bytes that will fit in returnedName, including the final NULL
See also
keyGetNameSize(), keyGetFullName(), keyGetFullNameSize()

◆ keyGetNameSize()

ssize_t keyGetNameSize ( const Key *  key)

Bytes needed to store the key name without owner.

For an empty key name you need one byte to store the ending NULL. For that reason 1 is returned.

Parameters
keythe key object to work with
Returns
number of bytes needed, including ending NULL, to store key name without owner
Return values
1if there is is no key Name
-1on NULL pointer
See also
keyGetName(), keyGetFullNameSize()
keyGetUnescapedNameSize to get size of unescaped name

◆ keyGetNamespace()

elektraNamespace keyGetNamespace ( const Key *  key)

For currently valid namespaces see elektraNamespace.

Since
0.8.10 Added method to kdbproposal.h

To handle every possible cases (including namespaces) a key can have:

switch (keyGetNamespace (k))
{
printf ("spec namespace\n");
break;
printf ("proc namespace\n");
break;
printf ("dir namespace\n");
break;
printf ("user namespace\n");
break;
printf ("system namespace\n");
break;
printf ("empty name\n");
break;
printf ("no key\n");
break;
printf ("metakey\n");
break;
printf ("cascading key\n");
break;
}

To loop over all valid namespaces use:

for (elektraNamespace ns = KEY_NS_FIRST; ns <= KEY_NS_LAST; ++ns)
{
// work with namespace
printf ("%d\n", ns);
}
Note
This method might be enhanced. You do not have any guarantee that, when for a specific name KEY_NS_META is returned today, that it still will be returned after the next recompilation. So make sure that your compiler gives you a warning for unhandled switches (gcc: -Wswitch or -Wswitch-enum if you want to handle default) and look out for those warnings.
Parameters
keythe key object to work with
Returns
the namespace of a key.

◆ keyGetUnescapedNameSize()

ssize_t keyGetUnescapedNameSize ( const Key *  key)

return size of unescaped name with embedded and terminating null characters

Parameters
keythe object to work with
See also
keyUnescapedName()
keyGetNameSize() for size of escaped variant
Return values
-1on null pointer
0if no name

◆ keyName()

const char* keyName ( const Key *  key)

Returns a pointer to the abbreviated real internal key name.

This is a much more efficient version of keyGetName() and can use it if you are responsible enough to not mess up things. You are not allowed to change anything in the returned array. The content of that string may change after keySetName() and similar functions. If you need a copy of the name, consider using keyGetName().

The name will be without owner, see keyGetFullName() if you need the name with its owner.

Return values
""when there is no keyName. The reason is
key=keyNew(0);
keySetName(key,"");
keyName(key); // you would expect "" here
keyDel(key);

Valid key names are:

  • spec/something for specification of other keys.
  • proc/something for in-memory keys, e.g. commandline.
  • dir/something for dir keys in current working directory
  • system/something for system keys in /etc or /
  • user/something for user keys in home directory
  • user:username/something for other users (deprecated: kdbGet() + kdbSet() currently unsupported)
  • /something for cascading keys (actually refers to one of the above, see also ksLookup())

    Note
    Note that the Key structure keeps its own size field that is calculated by library internal calls, so to avoid inconsistencies, you must never use the pointer returned by keyName() method to set a new value. Use keySetName() instead.
    Parameters
    keythe key object to work with
    Returns
    a pointer to the keyname which must not be changed.
    Return values
    ""when there is no (a empty) keyname
    0on NULL pointer
    See also
    keyGetNameSize() for the string length
    keyGetFullName(), keyGetFullNameSize() to get the full name
    keyGetName() as alternative to get a copy
    keyOwner() to get a pointer to owner
    keyUnescapedName to get an unescaped Key name

◆ keySetBaseName()

ssize_t keySetBaseName ( Key *  key,
const char *  baseName 
)

Sets baseName as the new basename for key.

Only the baseName will be affected and no other part of the key.

All text after the last '/' in the key keyname is erased and baseName is appended.

So let us suppose key has name "system/dir1/dir2/key1". If baseName is "key2", the resulting key name will be "system/dir1/dir2/key2". If baseName is empty or NULL, the resulting key name will be "system/dir1/dir2".

This function does proper escaping on the supplied name argument.

You can use all names to set as basename (e.g. . (dot), .. (dot-dot), % and "" (empty)). They will be properly escaped.

A simple example is:

If you want to add and not change the basename, use keyAddBaseName() instead. If you do not want escaping, use keyAddName() instead.

To add an inactive key name, use:

keySetName (k, "system/valid");
keySetBaseName (k, ".hiddenkey");
succeed_if_same_string (keyName (k), "system/.hiddenkey");
succeed_if_same_string (keyBaseName (k), ".hiddenkey");

When you want to add an array item, use:

keySetName (k, "system/valid");
keySetBaseName (k, "");
succeed_if_same_string (keyName (k), "system/%");
succeed_if_same_string (keyBaseName (k), "");
See also
Name Manipulation Methods for more details on special names
Parameters
keythe key object to work with
baseNamethe string used to overwrite the basename of the key
Returns
the size in bytes of the new key name
Return values
-1on NULL pointers
-1if key was inserted to a keyset before
See also
keyAddBaseName()
keySetName() to set a new name

◆ keySetName()

ssize_t keySetName ( Key *  key,
const char *  newName 
)

Set a new name to a key.

A valid name is one of the forms:

  • spec/something for specification of other keys.
  • proc/something for in-memory keys, e.g. commandline.
  • dir/something for dir keys in current working directory
  • system/something for system keys in /etc or /
  • user/something for user keys in home directory
  • user:username/something for other users (deprecated: kdbGet() + kdbSet() currently unsupported)
  • /something for cascading keys (actually refers to one of the above, see also ksLookup())

An invalid name either has an invalid namespace or a wrongly escaped \ at the end of the name.

See key names for the exact rules.

The last form has explicitly set the owner, to let the library know in which user folder to save the key. A owner is a user name. If it is not defined (the second form) current user is used.

You should always follow the guidelines for key tree structure creation.

A private copy of the key name will be stored, and the newName parameter can be freed after this call.

.., . and / will be handled as in filesystem paths. A valid name will be build out of the (valid) name what you pass, e.g. user///sw/../sw//././MyApp -> user/sw/MyApp

On invalid names, NULL or "" the name will be "" afterwards.

Return values
sizein bytes of this new key name including ending NULL
0if newName is an empty string or a NULL pointer (name will be empty afterwards)
-1if newName is invalid (name will be empty afterwards)
-1if key was inserted to a keyset before
Parameters
keythe key object to work with
newNamethe new key name
See also
keyNew(), keySetOwner()
keyGetName(), keyGetFullName(), keyName()
keySetBaseName(), keyAddBaseName() to manipulate a name

◆ keyUnescapedName()

const void* keyUnescapedName ( const Key *  key)

Returns a keyname which is null separated and does not use backslash for escaping.

Slashes are replaced with null bytes. So cascading keys start with a null byte. Otherwise escaped characters, e.g. non-hierarchy slash, will be unescaped.

This name is essential if you want to iterate over parts of the key name, want to compare keynames and want to check relations of keys in the hierarchy.

Parameters
keythe object to work with
See also
keyGetUnescapedNameSize()
keyName() for escaped variant
Return values
0on null pointers
""if no name
Returns
the name in its unescaped form