Elektra  0.8.10
Enumerations | Functions
Name Manipulation Methods
Key

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

Collaboration diagram for Name Manipulation Methods:

Enumerations

enum  elektraNamespace {
  KEY_NS_NONE =0, KEY_NS_EMPTY =1, KEY_NS_META =1<<1, KEY_NS_CASCADING =1<<2,
  KEY_NS_USER =1<<3, KEY_NS_SYSTEM =1<<4
}
 

Functions

const char * keyName (const Key *key)
 
ssize_t keyGetNameSize (const Key *key)
 
ssize_t keyGetName (const Key *key, char *returnedName, size_t maxSize)
 
ssize_t keySetName (Key *key, const char *newName)
 
ssize_t keyGetFullNameSize (const Key *key)
 
ssize_t keyGetFullName (const Key *key, char *returnedName, size_t maxSize)
 
elektraNamespace keyGetNamespace (const Key *key)
 
const char * keyBaseName (const Key *key)
 Returns a pointer to the internal unescaped key name where the basename starts.
 
ssize_t keyGetBaseNameSize (const Key *key)
 
ssize_t keyGetBaseName (const Key *key, char *returned, size_t maxSize)
 
ssize_t keyAddBaseName (Key *key, const char *baseName)
 
ssize_t keySetBaseName (Key *key, const char *baseName)
 
const char * keyOwner (const Key *key)
 
ssize_t keyGetOwnerSize (const Key *key)
 
ssize_t keyGetOwner (const Key *key, char *returnedOwner, size_t maxSize)
 
ssize_t keySetOwner (Key *key, const char *newOwner)
 

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 a unescaped separator.
  • A key base name (see keySetBaseName() and keyAddBaseName()) is the last part of the key name.
  • A namespace denotes the place the key comes from:
    • user keys come from user's home directories
    • system keys come from systems etc directories
  • A C-String is a null terminated sequence of characters. So \0 (null-character) must not occur within a C-String.
Note
The rules are currently not formally specified and are subject of change in the next major release. So, always prefer:
  • To use keySetName() and keyAddName() to get the canonified version of the keyname
  • To use keySetBaseName() and keyAddBaseName() to get an escaped key name part.
  • Not to escape or canonify with your own algorithms!
  • To use keyUnescapedName() and keyBaseName() to have access to the key name without escape sequences (key name parts are null terminated)
  • Not to unescape the strings yourself!
Syntax for Key Names
Key names and key name parts have following goals:
Semantics for Key Name Parts
  • % denotes an empty key name part.
Canonicalization for Key Names
  • / (slash) is the separator between key name parts.
  • // is shortened to /
  • trailing / (slashes) are removed
  • . (dot) and .. (dot-dot) is removed in an canonical key name, with following rules:
    • /./ is shortened to /
    • _/../ is shortened to _
Conventions for key names
  • Key name parts starting with # are array elements. Then only _ (underscore) followed by 0-9 is allowed. So we have the regular expression #[_]*[0-9]+ with the further limitation that the number of _ is defined by the number of digits-1.
  • Key name parts starting with _ are reserved for special purposes (if you use this within a plugin you still have to make sure _ is escaped properly)
  • Key name parts starting with @ are reserved for special purposes (if you use this within a plugin you still have to make sure @ is escaped properly)
  • If any key name part starts with . (dot) it means the key is inactive, see keyIsInactive().
Escaping rules
  • \ (backslash) is the escape character for the situations as described here (and only these). The \ character must only be escaped, when one of the following rules apply. So there is no stray escape character possible.
  • \/ allows to escape /
  • \\/ allows to use \ as character before / (and so on)
  • Use and . if you want your key name part to represent . and ..
  • \ and \. allows to use \ as character before . and .. (and so on)
  • Use \% if you want your key name part to start with % (and does not represent an empty name)
  • Use \\% allows to use \ as character before % (and so on)
Semantics for Key Name Specifications
  • _ denotes that the key name part is arbitrary (syntax as described above).
  • # denotes that the key name part has array syntax.
  • names surrounded by % (e.g. %profile%) denotes a placeholder.
Usage of Key Names
When using Elektra to store your application's configuration and state, please keep in mind the following rules:
  • Avoid to have your applications root right under system or user. (rationale: it would make the hierarchy too flat.)
  • Avoid the usage of characters other then a-z, 0-9 and _. (rationale: it would allow too many similar, confusing names.) (exceptions: if the user or a technology, decide about parts of the key name, this restriction does not apply, e.g. if the wlan essid is used as part of the key name)
  • It is suggested to make your application look for default keys under /sw/myapp/#/%/ where # is a major version number, e.g. #3 for the 4th version and % is a profile (% for default profile). This way, from a sysadmin perspective, it will be possible to copy the system/sw/myapp/#3/%/ tree to something like system/sw/myapp/#3/old/ and keep system clean and organized. Additionally, it is possible to start the old version of the app, using /sw/myapp/#2.

Enumeration Type Documentation

Elektra currently supported Key namespaces.

See Also
kdbGet(), keyGetNamespace()
Enumerator:
KEY_NS_NONE 

no key given as parameter to keyGetNamespace()

KEY_NS_EMPTY 

key name was empty, e.g. invalid key name

KEY_NS_META 

meta key, i.e. any key name not under other categories

KEY_NS_CASCADING 

cascading key, starts with /, abstract name for any of the namespaces below

KEY_NS_USER 

user key in the home directory of the current user

KEY_NS_SYSTEM 

system key not in the home directory, shared for a computer system

Function Documentation

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:

Key * k = keyNew("user/my/long", KEY_END);
keyAddBaseName(k, "myname");
printf ("%s\n", keyName(k)); // will print user/my/long/myname
keyDel(k);

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
-1 if the key had no name
-1 on NULL pointers
Return values
-1if key was inserted to a keyset before
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.
Parameters
keythe object to obtain the basename from
Returns
a pointer to the basename
"" when the key has no (base)name
0 on NULL pointer
See Also
keyGetBaseName(), keyGetBaseNameSize()
keyName() to get a pointer to the name
keyOwner() to get a pointer to the owner
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
1 on empty name
-1 on NULL pointers
-1 when maxSize is 0 or larger than SSIZE_MAX
See Also
keyBaseName(), keyGetBaseNameSize()
keyName(), keyGetName(), keySetName()
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()
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
1 on empty name
-1 on NULL pointers
-1 if 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
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
1 on empty name
-1 on NULL pointer
See Also
keyGetFullName(), keyGetNameSize()
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 malloc is not as failure tolerant and will try to allocate.

char *getBack = malloc (keyGetNameSize(key));
keyGetName(key, getBack, keyGetNameSize(key));
Returns
number of bytes written to returnedName
1 when only a null was written
-1 when 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()
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
1 if there is is no key Name
-1 on NULL pointer
See Also
keyGetName(), keyGetFullNameSize()
elektraNamespace keyGetNamespace ( const Key *  key)

For currently valid namespaces see elektraNamespace.

Version
0.8.10 Added method to kdbproposal.h
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.
ssize_t keyGetOwner ( const Key *  key,
char *  returnedOwner,
size_t  maxSize 
)

Return the owner of the key.

  • Given user:someuser/..... return someuser
  • Given user:some.user/.... return some.user
  • Given user/.... return the current user

Only user/... keys have a owner. For system/... keys (that doesn't have a key owner) an empty string ("") is returned.

Although usually the same, the owner of a key is not related to its UID. Owner are related to WHERE the key is stored on disk, while UIDs are related to mode controls of a key.

Parameters
keythe object to work with
returnedOwnera pre-allocated space to store the owner
maxSizemaximum number of bytes that fit returned
Returns
number of bytes written to buffer
1 if there is no owner
-1 on NULL pointers
-1 when maxSize is 0, larger than SSIZE_MAX or too small for ownername
See Also
keySetName(), keySetOwner(), keyOwner(), keyGetFullName()
ssize_t keyGetOwnerSize ( const Key *  key)

Return the size of the owner of the Key with concluding 0.

The returned number can be used to allocate a string. 1 will returned on an empty owner to store the concluding 0 on using keyGetOwner().

char * buffer;
buffer = malloc (keyGetOwnerSize (key));
// use buffer and keyGetOwnerSize (key) for maxSize
Note
that -1 might be returned on null pointer, so when you directly allocate afterwards its best to check if you will pass a null pointer before.
Parameters
keythe key object to work with
Returns
number of bytes
1 if there is no owner
-1 on NULL pointer
See Also
keyGetOwner()
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.

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

key=keyNew(0);
keySetName(key,"");
keyName(key); // you would expect "" here
keyDel(key);
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.
"" when there is no (a empty) keyname
0 on 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
const char* keyOwner ( const Key *  key)

Return a pointer to the real internal key owner.

This is a much more efficient version of keyGetOwner() and you should use it if you are responsible enough to not mess up things. You are not allowed to modify the returned string in any way. If you need a copy of the string, consider to use keyGetOwner() instead.

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

key=keyNew(0);
keySetOwner(key,"");
keyOwner(key); // you would expect "" here
keySetOwner(key,"system");
keyOwner(key); // you would expect "" here
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 keyOwner() method to set a new value. Use keySetOwner() instead.
Parameters
keythe key object to work with
Returns
a pointer to internal owner
Return values
""when there is no (a empty) owner
0iff key is a NULL pointer
See Also
keyGetOwnerSize() for the size of the string with concluding 0
keyGetOwner(), keySetOwner()
keyName() for name without owner
keyGetFullName() for name with owner
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:

Key * k = keyNew("user/my/long/name", KEY_END);
keySetBaseName(k, "myname");
printf ("%s\n", keyName(k)); // will print user/my/long/myname
keyDel(k);

If you do not want escaping, use keySetBaseName() instead. E.g. if you want to add an inactive key, use:

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

or when you want to add an array item, use:

keySetName (k, "system/valid");
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
-1 on NULL pointers
Return values
-1if key was inserted to a keyset before
See Also
keyAddBaseName()
keySetName() to set a new name
ssize_t keySetName ( Key *  key,
const char *  newName 
)

Set a new name to a key.

A valid name is of the forms:

  • system/something
  • user/something
  • user:username/something

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 pathes. 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
ssize_t keySetOwner ( Key *  key,
const char *  newOwner 
)

Set the owner of a key.

A owner is a name of a system user related to a UID. The owner decides on which location on the disc the key goes.

A private copy is stored, so the passed parameter can be freed after the call.

Parameters
keythe key object to work with
newOwnerthe string which describes the owner of the key
Returns
the number of bytes actually saved including final NULL
1 when owner is freed (by setting 0 or "")
-1 on null pointer or memory problems
See Also
keySetName(), keyGetOwner(), keyGetFullName()