KeySet * elektraMetaArrayToKS (Key * key, const char * metaName) { const Key * meta = keyGetMeta (key, metaName); if (!meta) return NULL; KeySet * result = ksNew (0, KS_END); if (keyString (meta)[0] != '#') { ksAppendKey (result, (Key *)meta); ksRewind (result); return result; } ksAppendKey (result, keyDup (meta)); Key * currentKey = keyDup (meta); keyAddName (currentKey, "#"); elektraArrayIncName (currentKey); Key * curMeta = NULL; while ((curMeta = (Key *)keyGetMeta (key, keyName (currentKey))) != NULL) { ksAppendKey (result, keyDup (curMeta)); elektraArrayIncName (currentKey); } keyDel (currentKey); ksRewind (result); return result; }
static void writeLineComments(Key *key, FILE *fp) { // TODO: this is really inefficient KeySet *metaKeys = elektraKeyGetMetaKeySet(key); Key *commentParent = keyNew("comment", KEY_META_NAME, KEY_END); KeySet *comments = elektraArrayGet(commentParent, metaKeys); keyDel(commentParent); ksRewind(comments); Key *current; while ((current = ksNext (comments))) { if (strcmp (keyName (current), "comment/#0")) { Key *spaceKey = keyDup (current); keyAddBaseName (spaceKey, "space"); Key *startKey = keyDup (current); keyAddBaseName (startKey, "start"); const char *spaces = getMetaValue (key, keyName (spaceKey)); const char *start = getMetaValue (key, keyName (startKey)); const char *comment = getMetaValue (key, keyName (current)); keyDel (spaceKey); keyDel (startKey); writeComment (spaces, start, comment, fp); fprintf (fp, "\n"); } } ksDel(metaKeys); ksDel(comments); }
static KeySet * nextPackage (FILE * fp, Key * parentKey) { char * line = elektraMalloc (DPKG_LINE_MAX); KeySet * package = ksNew (500, KS_END); Key * lastKey = NULL; Key * baseKey = NULL; int notDone = 0; while (fgets (line, DPKG_LINE_MAX, fp) != NULL) { if (*line == '\n') break; if (*line == ' ') { if (strchr (line, '\n')) notDone = 0; else notDone = 1; appendToKey (lastKey, line); } else if (notDone) { if (strchr (line, '\n')) notDone = 0; appendToKey (lastKey, line); } else { if (!strchr (line, '\n')) notDone = 1; char * section = line; char * data = strchr (line, ':'); if (data) *data = '\0'; ++data; // skip : ++data; // skip whitespace strtok (data, "\n"); // remove newline if (!strcmp (section, "Package")) { baseKey = keyDup (parentKey); keyAddBaseName (baseKey, data); lastKey = baseKey; ksAppendKey (package, baseKey); } else { Key * key = keyDup (baseKey); keyAddBaseName (key, section); keySetString (key, data); lastKey = key; ksAppendKey (package, key); } } memset (line, 0, DPKG_LINE_MAX); } elektraFree (line); return package; }
static void setSectionNumber(Key *parentKey, Key *key, KeySet *ks) { if (!strcmp(keyBaseName(key), INTERNAL_ROOT_SECTION)) { Key *tmpKey = keyDup(key); keySetMeta(tmpKey, "ini/section", "0"); keySetMeta(key, "ini/section", "0"); keySetString(tmpKey, 0); ksAppendKey(ks, tmpKey); keyDel(tmpKey); return; } Key *lookupKey = keyDup(key); Key *lastKey = keyDup(lookupKey); while (1) { if (!strcmp(keyName(lookupKey), keyName(parentKey))) { if (keyGetMeta(parentKey, "ini/lastSection")) { long previousSection = atol(keyString(keyGetMeta(parentKey, "ini/lastSection"))); ++previousSection; char buffer[21]; //20 digits (long) + \0 snprintf(buffer, sizeof (buffer), "%ld", previousSection); keySetMeta(parentKey, "ini/lastSection", buffer); keySetMeta(key, "ini/section", buffer); } else { keySetMeta(parentKey, "ini/lastSection", "1"); keySetMeta(parentKey, "ini/section", "0"); keySetMeta(key, "ini/section", "1"); } keySetMeta(lastKey, "ini/section", keyString(keyGetMeta(key, "ini/section"))); ksAppendKey(ks, lastKey); break; } if (keyGetMeta(ksLookup(ks, lookupKey, KDB_O_NONE), "ini/section")) { keySetMeta(key, "ini/section", keyString(keyGetMeta(ksLookup(ks, lookupKey, KDB_O_NONE), "ini/section"))); break; } keySetName(lastKey, keyName(lookupKey)); keyAddName(lookupKey, ".."); } keyDel(lookupKey); keyDel(lastKey); }
/** * @internal * Add plugin at placement to list plugin configuration and apply it. * * @param list List plugin * @param plugin Plugin to add * @param placement Placement name * @retval 0 on error * @retval 0 on success */ static int listAddPlugin (Plugin * list, Plugin * plugin, char * placement) { ELEKTRA_NOT_NULL (list); ELEKTRA_NOT_NULL (plugin); ELEKTRA_NOT_NULL (placement); KeySet * newConfig = ksDup (list->config); // Find name for next item in plugins array Key * configBase = keyNew ("user/plugins", KEY_END); KeySet * array = elektraArrayGet (configBase, newConfig); Key * pluginItem = elektraArrayGetNextKey (array); ELEKTRA_NOT_NULL (pluginItem); keySetString (pluginItem, plugin->name); keyDel (configBase); // Create key with plugin handle Key * pluginHandle = keyDup (pluginItem); keyAddName (pluginHandle, "handle"); keySetBinary (pluginHandle, &plugin, sizeof (plugin)); // Create key with plugin placement char * placementType = placementToListPositionType (placement); if (placementType == NULL) { keyDel (configBase); keyDel (pluginItem); keyDel (pluginHandle); return 0; } Key * pluginPlacements = keyDup (pluginItem); keyAddName (pluginPlacements, "placements/"); keyAddName (pluginPlacements, placementType); keySetString (pluginPlacements, placement); // Append keys to list plugin configuration ksAppendKey (newConfig, pluginItem); ksAppendKey (newConfig, pluginHandle); ksAppendKey (newConfig, pluginPlacements); ksDel (array); ksDel (list->config); // Apply new configuration list->config = newConfig; list->kdbOpen (list, NULL); return 1; }
int elektraLineRead (FILE * fp, KeySet * returned) { char * value = NULL; size_t len = 0; ssize_t n = 0; Key * read = NULL; // Read in each line while ((n = getline (&value, &len, fp)) != -1) { // Remove trailing newline if (value[n - 1] == '\n') { value[n - 1] = '\0'; } read = keyDup (ksTail (returned)); if (elektraArrayIncName (read) == -1) { elektraFree (value); keyDel (read); return -1; } keySetString (read, value); ksAppendKey (returned, read); } elektraFree (value); return 1; }
/** * @brief Remove ___empty_map if thats the only thing which would be * returned. * * @param returned to remove the key from */ static void elektraYajlParseSuppressEmpty (KeySet * returned, Key * parentKey) { if (ksGetSize (returned) == 2) { Key * lookupKey = keyDup (parentKey); keyAddBaseName (lookupKey, "___empty_map"); Key * toRemove = ksLookup (returned, lookupKey, KDB_O_POP); #ifdef ELEKTRA_YAJL_VERBOSE if (toRemove) { printf ("remove %s\n", keyName (toRemove)); } else { ksRewind (returned); Key * cur; while ((cur = ksNext (returned)) != 0) { printf ("key %s has value %s\n", keyName (cur), keyString (cur)); } printf ("did not find %s\n", keyName (lookupKey)); ksRewind (returned); } #endif if (toRemove) { keyDel (toRemove); } keyDel (lookupKey); } }
/** * @internal * Read placement list from plugin. * * The returned string needs to be freed. * * @param plugin Plugin * @return Space separated list of placement names */ static char * getPluginPlacementList (Plugin * plugin) { ELEKTRA_NOT_NULL (plugin); // Get placements from plugin Key * pluginInfo = keyNew ("system/elektra/modules/", KEY_END); keyAddBaseName (pluginInfo, plugin->name); KeySet * ksResult = ksNew (0, KS_END); plugin->kdbGet (plugin, ksResult, pluginInfo); Key * placementsKey = keyDup (pluginInfo); keyAddBaseName (placementsKey, "infos"); keyAddBaseName (placementsKey, "placements"); Key * placements = ksLookup (ksResult, placementsKey, 0); if (placements == NULL) { ELEKTRA_LOG_WARNING ("could not read placements from plugin"); return 0; } char * placementList = elektraStrDup (keyString (placements)); keyDel (pluginInfo); keyDel (placementsKey); ksDel (ksResult); return placementList; }
static void test_keyValue (const size_t storagePlugin, const char * tmpFile) { Key * parentKey = keyNew (TEST_ROOT_KEY, KEY_VALUE, tmpFile, KEY_END); open_storage_plugin (storagePlugin); Plugin * plugin = plugins[storagePlugin]; KeySet * ks = metaTestKeySet (); const char * name = "user/tests/storage/specialkey"; size_t valueSize = 42; void * value = elektraMalloc (valueSize); memset (value, 42, valueSize); Key * key = keyNew (name, KEY_END); keySetBinary (key, value, valueSize); ksAppendKey (ks, keyDup (key)); succeed_if (plugin->kdbSet (plugin, ks, parentKey) == 1, "kdbSet was not successful"); succeed_if (plugin->kdbGet (plugin, ks, parentKey) == 1, "kdbGet was not successful"); Key * found = ksLookupByName (ks, name, 0); succeed_if (found, "did not find key"); compare_key (key, found); elektraFree (value); keyDel (parentKey); ksDel (ks); keyDel (key); closeStoragePlugin (storagePlugin); }
static KeySet * getGlobKeys (Key * parentKey, KeySet * keys, enum GlobDirection direction) { KeySet * glob = ksNew (0, KS_END); Key * k = 0; size_t parentsize = keyGetNameSize (parentKey); Key * userGlobConfig = 0; Key * systemGlobConfig = 0; Key * userDirGlobConfig = 0; Key * systemDirGlobConfig = 0; userGlobConfig = keyNew ("user/glob", KEY_END); systemGlobConfig = keyNew ("system/glob", KEY_END); switch (direction) { case GET: userDirGlobConfig = keyNew ("user/glob/get", KEY_END); systemDirGlobConfig = keyNew ("system/glob/get", KEY_END); break; case SET: userDirGlobConfig = keyNew ("user/glob/set", KEY_END); systemDirGlobConfig = keyNew ("system/glob/set", KEY_END); break; } while ((k = ksNext (keys)) != 0) { /* use only glob keys for the current direction */ if (keyIsDirectBelow (userGlobConfig, k) || keyIsDirectBelow (systemGlobConfig, k) || keyIsDirectBelow (userDirGlobConfig, k) || keyIsDirectBelow (systemDirGlobConfig, k)) { keySetMeta (k, "glob/flags", getGlobFlags (keys, k)); /* Look if we have a string */ size_t valsize = keyGetValueSize (k); if (valsize < 2) continue; /* We now know we want that key. Dup it to not change the configuration. */ Key * ins = keyDup (k); /* Now look if we want cascading for the key */ if (keyString (k)[0] == '/') { char * newstring = elektraMalloc (valsize + parentsize); strcpy (newstring, keyName (parentKey)); strcat (newstring, keyString (k)); keySetString (ins, newstring); elektraFree (newstring); } ksAppendKey (glob, ins); } } keyDel (userGlobConfig); keyDel (systemGlobConfig); keyDel (userDirGlobConfig); keyDel (systemDirGlobConfig); return glob; }
static void test_keySetName (const size_t storagePlugin, const char * tmpFile) { Key * parentKey = keyNew (TEST_ROOT_KEY, KEY_VALUE, tmpFile, KEY_END); open_storage_plugin (storagePlugin); Plugin * plugin = plugins[storagePlugin]; KeySet * ks = metaTestKeySet (); succeed_if (plugin->kdbSet (plugin, ks, parentKey) == 1, "kdbSet was not successful"); succeed_if (plugin->kdbGet (plugin, ks, parentKey) == 1, "kdbGet was not successful"); Key * found = ksLookupByName (ks, "user/tests/storage/b", 0); succeed_if (found, "did not find key"); Key * duplicate = keyDup (found); keySetName (duplicate, "user/tests/storage/z"); keySetString (duplicate, "zzz"); KeySet * expected = metaTestKeySet (); compare_keyset (ks, expected); ksDel (expected); keyDel (duplicate); keyDel (parentKey); ksDel (ks); closeStoragePlugin (storagePlugin); }
// keyRel2 helper, turns key into a cascading key ( removes namespace) Key * keyAsCascading (const Key * key) { if (keyName (key)[0] == '/') { return keyDup (key); } else { const char * name = keyName (key); const char * ptr = strchr (name, '/'); if (!ptr) { return keyNew ("/", KEY_CASCADING_NAME, KEY_END); } else { ssize_t length = keyGetNameSize (key); if ((ptr - name) == (length - 1)) { return keyNew ("/", KEY_CASCADING_NAME, KEY_END); } else { return keyNew (ptr, KEY_CASCADING_NAME, KEY_END); } } } }
static void test_lookupNoOverride () { printf ("Test lookup with override not found\n"); // clang-format off Key *specKey = keyNew("/test/lift/limit", KEY_CASCADING_NAME, KEY_META, "default", "1", KEY_META, "override/#0", "/test/person_lift/limit", KEY_META, "override/#1", "/test/material_lift/limit", KEY_META, "override/#2", "/test/heavy_material_lift/limit", KEY_END); // clang-format on Key * dup = keyDup (specKey); Key * k1 = 0; Key * k2 = 0; KeySet * ks = ksNew (20, k1 = keyNew ("user/test/lift/limit", KEY_VALUE, "22", KEY_END), k2 = keyNew ("/test/person_lift/limit", KEY_CASCADING_NAME, KEY_VALUE, "10", KEY_END), KS_END); succeed_if (ksLookup (ks, specKey, KDB_O_SPEC) == k1, "found wrong key"); succeed_if (ksLookup (ks, dup, KDB_O_SPEC) == k1, "found wrong key"); elektraKeySetName (dup, "/test/lift/limit", KEY_CASCADING_NAME); succeed_if (ksLookup (ks, dup, KDB_O_SPEC) == k1, "found wrong key"); succeed_if (ksLookup (ks, dup, KDB_O_SPEC | KDB_O_CREATE) == k1, "found wrong key"); keyDel (specKey); ksDel (ks); keyDel (dup); }
void check_reversibility (const char * msg) { Key * decode = keyNew ("user/test", KEY_VALUE, msg, KEY_END); CHexData * hd = calloc (1, sizeof (CHexData)); hd->hd['\0'] = 1; hd->hd['\n'] = 1; hd->hd['\\'] = 1; hd->hd[' '] = 1; hd->hd['='] = 1; hd->hd[';'] = 1; hd->hd['#'] = 1; hd->escape = '\\'; char buf[1000]; hd->buf = buf; Key * encode = keyDup (decode); elektraHexcodeEncode (encode, hd); elektraHexcodeDecode (encode, hd); compare_key (encode, decode); elektraFree (hd); keyDel (decode); keyDel (encode); }
/** * @brief Takes the first key and cuts off this common part * for all other keys, instead name will be prepended * * @return a new allocated keyset with keys in user namespace. * * The first key is removed in the resulting keyset. */ KeySet* elektraRenameKeys(KeySet *config, const char* name) { Key *root; Key *cur; ssize_t rootSize = 0; ksRewind(config); root = ksNext (config); rootSize = keyGetNameSize(root); keyDel (ksLookup (config, root, KDB_O_POP)); KeySet *newConfig = ksNew(ksGetSize(config), KS_END); if (rootSize == -1) return newConfig; while ((cur = ksPop(config)) != 0) { Key *dupKey = keyDup(cur); keySetName(dupKey, name); keyAddName(dupKey, keyName(cur)+rootSize-1); ksAppendKey(newConfig, dupKey); keyDel(cur); } return newConfig; }
char * elektraMetaArrayToString (Key * key, const char * metaName, const char * delim) { char * result = NULL; Key * lookupElem = keyDup (keyGetMeta (key, metaName)); keyAddBaseName (lookupElem, "#0"); Key * elem = (Key *)keyGetMeta (key, keyName (lookupElem)); if (elem != NULL) { elektraRealloc ((void **)&result, keyGetValueSize (elem)); snprintf (result, keyGetValueSize (elem), "%s", keyString (elem)); } elektraArrayIncName (lookupElem); elem = (Key *)keyGetMeta (key, keyName (lookupElem)); while (elem != NULL) { elektraRealloc ((void **)&result, elektraStrLen (result) + keyGetValueSize (elem) + 1); // String (incl. +2 times \0) + delimiter + whitespace strcat (result, delim); strcat (result, keyString (elem)); elektraArrayIncName (lookupElem); elem = (Key *)keyGetMeta (key, keyName (lookupElem)); } keyDel (lookupElem); return result; }
static void validateWildcardSubs (KeySet * ks, Key * key, Key * specKey) { const Key * requiredMeta = keyGetMeta (specKey, "required"); if (!requiredMeta) return; Key * tmpParent = keyDup (key); keySetBaseName (tmpParent, 0); Key * parent = ksLookup (ks, tmpParent, KDB_O_NONE); keyDel (tmpParent); if (parent == NULL) return; KeySet * ksCopy = ksDup (ks); KeySet * subKeys = ksCut (ksCopy, parent); Key * cur; long subCount = 0; while ((cur = ksNext (subKeys)) != NULL) { if (keyIsDirectBelow (parent, cur)) ++subCount; } long required = atol (keyString (requiredMeta)); if (required != subCount) { char buffer[MAX_CHARS_IN_LONG + 1]; snprintf (buffer, sizeof (buffer), "%ld", subCount); keySetMeta (parent, "conflict/invalid/subcount", buffer); } ksDel (subKeys); ksDel (ksCopy); }
/** * @brief return only those keys from the given * keyset that pass the supplied filter function * with the supplied argument * * @param result the keyset that should contain the filtered keys * @param input the keyset whose keys should be filtered * @param filter a function pointer to a function that will be used to * filter the keyset. A key will be taken if the function returns a value * greater than 0. * @param argument an argument that will be passed to the filter function * each time it is called * @return the number of filtered keys if the filter function always * returned a positive value, -1 otherwise * @retval NULL on NULL pointer */ int elektraKsFilter (KeySet *result, KeySet *input, int (*filter) (const Key *k, void *argument), void *argument) { if (!result) return -1; if (!input) return -1; if (!filter) return -1; int rc = 0; int ret = 0; Key *current; cursor_t cursor = ksGetCursor (input); ksRewind (input); while ((current = ksNext (input)) != 0) { rc = filter (current, argument); if (rc <= -1) return -1; else if (rc > 0) { ++ ret; ksAppendKey(result, keyDup (current)); } } ksSetCursor(input, cursor); return ret; }
static void test_withoutConfig() { Key *parentKey = keyNew ("user/tests/rename", KEY_END); Key *parentKeyCopy = keyDup(parentKey); KeySet *conf = ksNew (0, KS_END); PLUGIN_OPEN("rename"); KeySet *ks = createSimpleTestKeys(); ksAppendKey(ks, parentKey); succeed_if(plugin->kdbGet (plugin, ks, parentKey) >= 1, "call to kdbGet was not successful"); succeed_if(output_error (parentKey), "error in kdbGet"); succeed_if(output_warnings (parentKey), "warnings in kdbGet"); KeySet *expected = createSimpleTestKeys(); ksAppendKey(expected, parentKeyCopy); compareKeySets(ks, expected); keyDel (parentKey); keyDel (parentKeyCopy); ksDel(expected); ksDel(ks); PLUGIN_CLOSE (); }
/** * @brief sets mountpoint * * @param backend where the mountpoint should be set * @param elektraConfig the config where the mountpoint can be found * @param [out] errorKey the name also has the mountpoint set * * @pre ksCurrent() is root key * @post ksCurrent() is root key * * @retval -1 if no mountpoint is found or memory allocation problem * @retval 0 on success */ int elektraBackendSetMountpoint(Backend *backend, KeySet *elektraConfig, Key *errorKey) { Key * root = ksCurrent(elektraConfig); Key * searchMountpoint = keyDup(root); keyAddBaseName(searchMountpoint, "mountpoint"); Key * foundMountpoint = ksLookup(elektraConfig, searchMountpoint, 0); keyDel (searchMountpoint); ksLookup(elektraConfig, root, 0); // reset ksCurrent() if (!foundMountpoint) { ELEKTRA_ADD_WARNINGF(14, errorKey, "Could not find mountpoint within root %s", keyName(root)); return -1; } backend->mountpoint = keyNew("", KEY_VALUE, keyBaseName(root), KEY_END); elektraKeySetName(backend->mountpoint, keyString(foundMountpoint), KEY_CASCADING_NAME | KEY_EMPTY_NAME); keySetName(errorKey, keyName(backend->mountpoint)); if (!backend->mountpoint) { ELEKTRA_ADD_WARNINGF(14, errorKey, "Could not create mountpoint with name %s and value %s", keyString(foundMountpoint), keyBaseName(root)); return -1; } keyIncRef(backend->mountpoint); return 0; }
static int iniSectionToElektraKey (void *vhandle, const char *section) { CallbackHandle *handle = (CallbackHandle *)vhandle; Key *appendKey = keyDup (handle->parentKey); keySetMeta(appendKey, "ini/lastSection", 0); createUnescapedKey(appendKey, section); Key *existingKey = NULL; if ((existingKey = ksLookup(handle->result, appendKey, KDB_O_NONE))) { keyDel(appendKey); if(!handle->mergeSections) { ELEKTRA_SET_ERRORF(140, handle->parentKey, "Section name: %s\n", section); return 0; } keySetMeta(existingKey, "ini/duplicate", ""); return 1; } setSectionNumber(handle->parentKey, appendKey, handle->result); setOrderNumber(handle->parentKey, appendKey); keySetBinary(appendKey, 0, 0); flushCollectedComment (handle, appendKey); ksAppendKey(handle->result, appendKey); return 1; }
static void flushConvertedKeys (Key * target, KeySet * converted, KeySet * orig) { if (ksGetSize (converted) == 0) return; ksRewind (converted); Key * current; Key * appendTarget; while ((current = ksNext (converted))) { appendTarget = target; const char * metaName = keyString (keyGetMeta (current, CONVERT_METANAME)); Key * currentDup = keyDup (current); Key * targetDup = keyDup (appendTarget); keySetBaseName (currentDup, 0); keySetBaseName (targetDup, 0); /* the convert key request to be converted to a key * on the same level, but the target is below or above */ if (keyGetMeta (current, CONVERT_APPEND_SAMELEVEL) && keyCmp (currentDup, targetDup)) { appendTarget = 0; } keyDel (currentDup); keyDel (targetDup); /* no target key was found of the target * was discarded for some reason. Revert to the parent */ if (!appendTarget) { appendTarget = findNearestParent (current, orig); } elektraKeyAppendMetaLine (appendTarget, metaName, keyString (current)); removeKeyFromResult (current, target, orig); } ksClear (converted); }
/** * @internal * Remove plugin at all placements from list plugin configuration and apply it. * * @param list List plugin * @param plugin Plugin to remove * @retval 0 on error * @retval 1 on success */ static int listRemovePlugin (Plugin * list, Plugin * plugin) { ELEKTRA_NOT_NULL (list); ELEKTRA_NOT_NULL (plugin); KeySet * newConfig = ksDup (list->config); Key * configBase = keyNew ("user/plugins", KEY_END); KeySet * array = elektraArrayGet (configBase, newConfig); // Find the plugin with our handle Key * current; ksRewind (array); while ((current = ksNext (array)) != NULL) { Key * handleLookup = keyDup (current); keyAddBaseName (handleLookup, "handle"); Key * handle = ksLookup (newConfig, handleLookup, 0); keyDel (handleLookup); if (handle) { Plugin * handleValue = (*(Plugin **) keyValue (handle)); if (handleValue == plugin) { // Remove plugin configuration KeySet * cut = ksCut (newConfig, current); ksDel (cut); } } } ksDel (array); // Renumber array items KeySet * sourceArray = elektraArrayGet (configBase, newConfig); Key * renumberBase = keyNew ("user/plugins/#", KEY_END); ksRewind (sourceArray); while ((current = ksNext (sourceArray)) != NULL) { // Create new array item base name e.g. "user/plugins/#0" elektraArrayIncName (renumberBase); moveKeysRecursive (keyName (current), keyName (renumberBase), newConfig); } keyDel (configBase); keyDel (renumberBase); ksDel (sourceArray); ksDel (list->config); // Apply new configuration list->config = newConfig; list->kdbOpen (list, NULL); return 1; }
/** * Set the raw string value of an array element key. * * @param elektra The Elektra instance to use. * @param name The (relative) name of the array. * @param index The index of the array element. * @param value The raw value to set. * @param type The type to set in the metadata of the (array element) key. * @param error Pointer to an ElektraError. Will be set in case saving fails. */ void elektraSetRawStringArrayElement (Elektra * elektra, const char * name, size_t index, const char * value, KDBType type, ElektraError ** error) { CHECK_ERROR (elektra, error); elektraSetArrayLookupKey (elektra, name, index); Key * const key = keyDup (elektra->lookupKey); keySetMeta (key, "type", type); keySetString (key, value); elektraSaveKey (elektra, key, error); }
void elektraMetaArrayAdd (Key * key, const char * metaName, const char * value) { const Key * meta = keyGetMeta (key, metaName); Key * arrayKey; if (!meta) { keySetMeta (key, metaName, "#0"); arrayKey = keyDup (keyGetMeta (key, metaName)); keySetString (arrayKey, 0); keyAddBaseName (arrayKey, "#"); } else { arrayKey = keyDup (meta); keyAddBaseName (arrayKey, keyString (meta)); } elektraArrayIncName (arrayKey); keySetMeta (key, keyName (arrayKey), value); keySetMeta (key, metaName, keyBaseName (arrayKey)); keyDel (arrayKey); }
static void elektraAddUname (KeySet * returned, Key * parentKey) { Key * dir; Key * key = keyDup (parentKey); ksAppendKey (returned, key); struct utsname buf; uname (&buf); // TODO: handle error dir = keyDup (parentKey); keyAddBaseName (dir, "sysname"); keySetString (dir, buf.sysname); ksAppendKey (returned, dir); dir = keyDup (parentKey); keyAddBaseName (dir, "nodename"); keySetString (dir, buf.nodename); ksAppendKey (returned, dir); dir = keyDup (parentKey); keyAddBaseName (dir, "release"); keySetString (dir, buf.release); ksAppendKey (returned, dir); dir = keyDup (parentKey); keyAddBaseName (dir, "version"); keySetString (dir, buf.version); ksAppendKey (returned, dir); dir = keyDup (parentKey); keyAddBaseName (dir, "machine"); keySetString (dir, buf.machine); ksAppendKey (returned, dir); }
/** * @internal * Create a new key with a different root or common name. * * Does not modify `key`. The new key needs to be freed after usage. * * Preconditions: The key name starts with `source`. * * Example: * ``` * Key * source = keyNew("user/plugins/foo/placements/get", KEY_END); * Key * dest = renameKey ("user/plugins/foo", "user/plugins/bar", source); * succeed_if_same_string (keyName(dest), "user/plugins/bar/placements/get"); * ``` * * * @param source Part of the key name to replace * @param dest Replaces `source` * @param key key * @return key with new name */ static Key * renameKey (const char * source, const char * dest, Key * key) { const char * name = keyName (key); char * baseKeyNames = strndup (name + strlen (source), strlen (name)); Key * moved = keyDup (key); keySetName (moved, dest); keyAddName (moved, baseKeyNames); elektraFree (baseKeyNames); return moved; }
static int iniSectionToElektraKey (void *vconfig, const char *section) { Configuration *config = (Configuration *)vconfig; Key *appendKey = keyDup (config->parentKey); keyAddBaseName(appendKey, section); writeCommentToMeta (config, appendKey); keySetDir(appendKey); ksAppendKey(config->result, appendKey); return 1; }
static KeySet * pwentToKS (struct passwd * pwd, Key * parentKey, SortBy index) { KeySet * ks = ksNew (0, KS_END); Key * append = keyNew (keyName (parentKey), KEY_END); char id[ID_MAX_CHARACTERS]; if (index == UID) { snprintf (id, sizeof (id), "%u", pwd->pw_uid); keyAddBaseName (append, id); keySetBinary (append, 0, 0); ksAppendKey (ks, keyDup (append)); keyAddBaseName (append, "name"); keySetString (append, pwd->pw_name); } else { keyAddBaseName (append, pwd->pw_name); keySetBinary (append, 0, 0); ksAppendKey (ks, keyDup (append)); snprintf (id, sizeof (id), "%u", pwd->pw_uid); keyAddBaseName (append, "uid"); keySetString (append, id); } ksAppendKey (ks, keyDup (append)); keySetString (append, 0); keySetBaseName (append, "shell"); keySetString (append, pwd->pw_shell); ksAppendKey (ks, keyDup (append)); keySetString (append, 0); keySetBaseName (append, "home"); keySetString (append, pwd->pw_dir); ksAppendKey (ks, keyDup (append)); keySetString (append, 0); keySetBaseName (append, "gid"); snprintf (id, sizeof (id), "%u", pwd->pw_gid); keySetString (append, id); ksAppendKey (ks, keyDup (append)); keySetString (append, 0); keySetBaseName (append, "passwd"); keySetString (append, pwd->pw_passwd); ksAppendKey (ks, keyDup (append)); keySetString (append, 0); keySetBaseName (append, "gecos"); keySetString (append, pwd->pw_gecos); ksAppendKey (ks, keyDup (append)); keyDel (append); return ks; }
static const char * getGlobFlags (KeySet * keys, Key * globKey) { Key * flagKey = keyDup (globKey); keyAddBaseName (flagKey, "flags"); Key * flagResult = ksLookup (keys, flagKey, KDB_O_NONE); keyDel (flagKey); if (flagResult) { return keyString (flagResult); } return 0; }