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); }
/** * @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 void test_lookupDefaultCascading () { printf ("Test lookup default with cascading\n"); Key * specKey = keyNew ("/abc", KEY_CASCADING_NAME, KEY_END); Key * k = 0; KeySet * ks = ksNew (20, KS_END); succeed_if (ksGetSize (ks) == 0, "wrong size"); succeed_if (ksLookup (ks, specKey, KDB_O_SPEC) == 0, "found wrong key"); keySetMeta (specKey, "default", "xyz"); k = ksLookup (ks, specKey, KDB_O_SPEC); succeed_if (k != 0, "found no default key"); succeed_if (ksGetSize (ks) == 1, "wrong size"); succeed_if_same_string (keyName (k), "/abc"); succeed_if_same_string (keyString (k), "xyz"); succeed_if (ksLookup (ks, specKey, KDB_O_SPEC) == k, "did not find default key again"); succeed_if (ksGetSize (ks) == 1, "wrong size"); keySetMeta (specKey, "default", ""); succeed_if (ksLookup (ks, specKey, KDB_O_SPEC) == k, "did not find default key again"); succeed_if (ksGetSize (ks) == 1, "wrong size"); keyDel (specKey); ksDel (ks); }
static void test_cascadingLookup (void) { printf ("test cascading lookup\n"); Key * k0; Key * k1; Key * k2; Key * k3; KeySet * ks = ksNew (10, k0 = keyNew ("system/benchmark/override/#0", 0), k1 = keyNew ("system/benchmark/override/#1", 0), k2 = keyNew ("user/benchmark/override/#2", 0), k3 = keyNew ("user/benchmark/override/#3", 0), KS_END); Key * search = keyNew ("/benchmark/override/#0", KEY_CASCADING_NAME, KEY_END); Key * found = ksLookup (ks, search, 0); succeed_if (found == k0, "found wrong key"); elektraKeySetName (search, "/benchmark/override/#1", KEY_CASCADING_NAME); found = ksLookup (ks, search, 0); succeed_if (found == k1, "found wrong key"); keyDel (search); search = keyNew ("/benchmark/override/#2", KEY_CASCADING_NAME, KEY_END); found = ksLookup (ks, search, 0); succeed_if (found == k2, "found wrong key"); elektraKeySetName (search, "/benchmark/override/#3", KEY_CASCADING_NAME); found = ksLookup (ks, search, 0); succeed_if (found == k3, "found wrong key"); keyDel (search); ksDel (ks); }
static void test_ksLookup (const size_t storagePlugin, const char * tmpFile, option_t options) { Key * parentKey = keyNew (TEST_ROOT_KEY, KEY_VALUE, tmpFile, KEY_END); open_storage_plugin (storagePlugin); Plugin * plugin = plugins[storagePlugin]; KeySet * ks = simpleTestKeySet (); 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 * lookup = keyNew ("user/tests/storage/simpleKey/a", KEY_END); Key * found = ksLookup (ks, lookup, options); succeed_if (found, "did not find key"); if (options == KDB_O_POP) { // make sure key is really popped keyDel (found); found = ksLookup (ks, lookup, 0); succeed_if (!found, "found key that should not exist"); } keyDel (lookup); lookup = keyNew ("user/tests/storage/simpleKey/foo", KEY_END); found = ksLookup (ks, lookup, options); succeed_if (!found, "found key that should not exist"); keyDel (lookup); keyDel (parentKey); ksDel (ks); closeStoragePlugin (storagePlugin); }
/**Do a shallow copy of metadata from source to dest. * * The key dest will have the same metadata referred with * metaName afterwards then source. * * For example the metadata type is copied into the * Key k. * * @code void l(Key *k) { // receive c keyCopyMeta(k, c, "type"); // the caller will see the changed key k // with the metadata "type" from c } * @endcode * * The main purpose of this function is for plugins or * applications which want to add the same metadata to * n keys. When you do that with keySetMeta() it will * take n times the memory for the key. This can be * considerable amount of memory for many keys with * some metadata for each. * * To avoid that problem you can use keyCopyAllMeta() * or keyCopyMeta(). * * @code void o(KeySet *ks) { Key *current; Key *shared = keyNew (0); keySetMeta(shared, "shared", "this metadata should be shared among many keys"); ksRewind(ks); while ((current = ksNext(ks)) != 0) { if (needs_shared_data(current)) keyCopyMeta(current, shared, "shared"); } } * @endcode * * @post keyGetMeta(source, metaName) == keyGetMeta(dest, metaName) * * @retval 1 if was successfully copied * @retval 0 if the metadata in dest was removed too * @retval -1 on null pointers (source or dest) * @retval -1 on memory problems * @param dest the destination where the metadata should be copied too * @param source the key where the metadata should be copied from * @param metaName the name of the metadata which should be copied * @ingroup keymeta */ int keyCopyMeta (Key * dest, const Key * source, const char * metaName) { Key * ret; if (!source) return -1; if (!dest) return -1; if (dest->flags & KEY_FLAG_RO_META) return -1; ret = (Key *)keyGetMeta (source, metaName); if (!ret) { /*Make sure that dest also does not have metaName*/ if (dest->meta) { Key * r; r = ksLookup (dest->meta, ret, KDB_O_POP); if (r) { /*It was already there, so lets drop that one*/ keyDel (r); } } return 0; } /*Lets have a look if the key is already inserted.*/ if (dest->meta) { Key * r; r = ksLookup (dest->meta, ret, KDB_O_POP); if (r) { /*It was already there, so lets drop that one*/ keyDel (r); } } else { /*Create a new place for meta information.*/ dest->meta = ksNew (0, KS_END); if (!dest->meta) { return -1; } } // now we can simply append that key ksAppendKey (dest->meta, ret); return 1; }
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); }
/** * Checks whether a given path must be pruned from the Augeas tree by comparing * it with the supplied keyset. If any operation during pruning fails, an error * is returned in order to prevent invalid keys. */ static int removeOrphan (augeas * handle, const char * treePath, void * data) { int result; struct OrphanSearch * orphanData = (struct OrphanSearch *)data; Key * key = createKeyFromPath (orphanData->parentKey, treePath); if (!ksLookup (orphanData->ks, key, KDB_O_NONE)) { char * nodeMatch; char ** matches; result = asprintf (&nodeMatch, "%s/*", treePath); if (result < 0) return -1; int numChildNodes = aug_match (handle, nodeMatch, &matches); elektraFree (nodeMatch); /* if the node is a leaf node we can safely delete it */ if (numChildNodes == 0) { aug_rm (handle, treePath); } else { short pruneTree = 1; for (int i = 0; i < numChildNodes; i++) { Key * childKey = createKeyFromPath (orphanData->parentKey, matches[i]); if (ksLookup (orphanData->ks, childKey, KDB_O_NONE)) { pruneTree = 0; } keyDel (childKey); elektraFree (matches[i]); } elektraFree (matches); if (pruneTree) { aug_rm (handle, treePath); } } } keyDel (key); return 0; }
/** * @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; }
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; }
/** @retval 0 if ksCurrent does not hold an array entry @retval 1 if the array entry will be used because its the first @retval 2 if a new array entry was created @retval -1 error in snprintf */ static int elektraYajlIncrementArrayEntry (KeySet * ks) { Key * current = ksCurrent (ks); const char * baseName = keyBaseName (current); if (baseName && *baseName == '#') { current = keyNew (keyName (current), KEY_END); if (!strcmp (baseName, "###empty_array")) { // get rid of previous key keyDel (ksLookup (ks, current, KDB_O_POP)); // we have a new array entry keySetBaseName (current, 0); keyAddName (current, "#0"); ksAppendKey (ks, current); return 1; } else { // we are in an array elektraArrayIncName (current); ksAppendKey (ks, current); return 2; } } else { // previous entry indicates this is not an array return 0; } }
/** * @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); } }
static int elektraYajlParseEnd (void * ctx) { KeySet * ks = (KeySet *)ctx; Key * currentKey = ksCurrent (ks); Key * lookupKey = keyNew (keyName (currentKey), KEY_END); keySetBaseName (lookupKey, 0); // remove current baseName // lets point current to the correct place Key * foundKey = ksLookup (ks, lookupKey, 0); #ifdef ELEKTRA_YAJL_VERBOSE if (foundKey) { printf ("elektraYajlParseEnd %s\n", keyName (foundKey)); } else { printf ("elektraYajlParseEnd did not find key!\n"); } #else (void)foundKey; // foundKey is not used, but lookup is needed #endif keyDel (lookupKey); return 1; }
static int elektraYajlParseMapKey (void * ctx, const unsigned char * stringVal, yajl_size_type stringLen) { KeySet * ks = (KeySet *)ctx; elektraYajlIncrementArrayEntry (ks); Key * currentKey = keyNew (keyName (ksCurrent (ks)), KEY_END); keySetString (currentKey, 0); unsigned char delim = stringVal[stringLen]; char * stringValue = (char *)stringVal; stringValue[stringLen] = '\0'; #ifdef ELEKTRA_YAJL_VERBOSE printf ("elektraYajlParseMapKey stringValue: %s currentKey: %s\n", stringValue, keyName (currentKey)); #endif if (currentKey && !strcmp (keyBaseName (currentKey), "___empty_map")) { // remove old key keyDel (ksLookup (ks, currentKey, KDB_O_POP)); // now we know the name of the object keySetBaseName (currentKey, stringValue); } else { // we entered a new pair (inside the previous object) keySetBaseName (currentKey, stringValue); } ksAppendKey (ks, currentKey); // restore old character in buffer stringValue[stringLen] = delim; return 1; }
static KeySet * prepareGlobalKS (KeySet * ks, Key * parentKey) { ksRewind (ks); Key * cutKey = keyNew ("/", KEY_CASCADING_NAME, KEY_END); keyAddName (cutKey, strchr (keyName (parentKey), '/')); KeySet * cutKS = ksCut (ks, cutKey); Key * specCutKey = keyNew ("spec", KEY_END); KeySet * specCut = ksCut (cutKS, specCutKey); ksRewind (specCut); Key * cur; while ((cur = ksNext (specCut)) != NULL) { if (keyGetNamespace (cur) == KEY_NS_CASCADING) { ksAppendKey (cutKS, cur); keyDel (ksLookup (specCut, cur, KDB_O_POP)); } } ksAppend (ks, specCut); ksDel (specCut); keyDel (specCutKey); keyDel (cutKey); ksRewind (cutKS); return cutKS; }
/** * @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 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); }
static void test_plainIniEmptyWrite (char * fileName) { Key * parentKey = keyNew ("user/tests/ini-write", KEY_VALUE, elektraFilename (), KEY_END); KeySet * conf = ksNew (0, KS_END); PLUGIN_OPEN ("ini"); KeySet * ks = ksNew (30, keyNew ("user/tests/ini-write/nosectionkey", KEY_VALUE, "nosectionvalue", KEY_END), keyNew ("user/tests/ini-write/section1", KEY_BINARY, KEY_END), keyNew ("user/tests/ini-write/section1/key1", KEY_VALUE, "value1", KEY_END), keyNew ("user/tests/ini-write/section1/key2", KEY_VALUE, "value2", KEY_END), keyNew ("user/tests/ini-write/section2", KEY_BINARY, KEY_END), keyNew ("user/tests/ini-write/section2/key3", KEY_VALUE, "value3", KEY_END), keyNew ("user/tests/ini-write/section2/emptykey", KEY_META, "ini/empty", "", KEY_END), KS_END); succeed_if (plugin->kdbSet (plugin, ks, parentKey) >= 1, "call to kdbSet was not successful"); succeed_if (output_error (parentKey), "error in kdbSet"); succeed_if (output_warnings (parentKey), "warnings in kdbSet"); succeed_if (compare_line_files (srcdir_file (fileName), keyString (parentKey)), "files do not match as expected"); KeySet * readKS = ksNew (0, KS_END); succeed_if (plugin->kdbGet (plugin, readKS, parentKey) >= 0, "kdbGet failed"); const Key * meta; Key * searchKey = keyNew ("user/tests/ini-write/section2/emptykey", KEY_META, "ini/empty", "", KEY_END); Key * key = ksLookup (readKS, searchKey, KDB_O_NONE); meta = keyGetMeta (key, "ini/empty"); succeed_if (meta != NULL, "reading empty key again failed"); ksDel (readKS); keyDel (parentKey); keyDel (searchKey); ksDel (ks); PLUGIN_CLOSE (); }
static void test_lookupNoascading () { printf ("Test lookup without cascading\n"); Key * specKey = keyNew ("/abc", KEY_CASCADING_NAME, KEY_END); Key * d = keyDup (specKey); keySetString (d, "dup"); succeed_if_same_string (keyName (specKey), "/abc"); succeed_if_same_string (keyName (d), "/abc"); succeed_if (!keyCmp (d, specKey), "comparision to duplicate failed"); succeed_if_same_string (keyName (d), "/abc"); succeed_if_same_string (keyName (specKey), "/abc"); KeySet * ks = ksNew (20, d, KS_END); Key * k = ksLookup (ks, specKey, KDB_O_NOCASCADING); succeed_if_same_string (keyName (specKey), "/abc"); succeed_if (k != 0, "did not find cascading key"); succeed_if (k != specKey, "should not be specKey"); succeed_if (k == d, "should be dup key"); Key * a = keyNew (keyName (specKey), KEY_CASCADING_NAME, KEY_VALUE, "a", KEY_END); ksAppendKey (ks, a); for (int i = 0; i < 5; ++i) { k = ksLookup (ks, specKey, KDB_O_NOCASCADING); succeed_if (keyGetNameSize (specKey) == 5, "size of spec key wrong"); succeed_if_same_string (keyName (specKey), "/abc"); succeed_if (k != 0, "did not find cascading key"); succeed_if (k != specKey, "should not be specKey"); succeed_if (k == a, "should be dup key"); // search without cascading k = ksLookup (ks, specKey, 0); succeed_if (keyGetNameSize (specKey) == 5, "size of spec key wrong"); succeed_if_same_string (keyName (specKey), "/abc"); succeed_if (k != 0, "did not find cascading key"); succeed_if (k != specKey, "should not be specKey"); succeed_if (k == a, "should be dup key"); } ksDel (ks); keyDel (specKey); }
static void test_preserveEmptyLines (char * fileName) { Key * parentKey = keyNew ("user/tests/ini-write", KEY_VALUE, srcdir_file (fileName), KEY_END); Key * writeParentKey = keyNew ("user/tests/ini-write", KEY_VALUE, elektraFilename (), KEY_END); KeySet * conf = ksNew (0, KS_END); KeySet * ks = ksNew (30, KS_END); PLUGIN_OPEN ("ini"); succeed_if (plugin->kdbGet (plugin, ks, parentKey) >= 0, "call to kdbGet was not successful"); keyDel (ksLookup (ks, parentKey, KDB_O_POP)); keyDel (parentKey); succeed_if (plugin->kdbSet (plugin, ks, writeParentKey) >= 1, "call to kdbSet was not successful"); succeed_if (compare_line_files (srcdir_file (fileName), keyString (writeParentKey)), "files do not match as expected"); keyDel (ksLookup (ks, writeParentKey, KDB_O_POP)); keyDel (writeParentKey); ksDel (ks); PLUGIN_CLOSE (); }
void removeKeyFromResult (Key * convertKey, Key * target, KeySet * orig) { /* remember which key this key was converted to * before removing it from the result */ keySetMeta (convertKey, CONVERT_TARGET, keyName (target)); Key * key = ksLookup (orig, convertKey, KDB_O_POP); keyDel (key); }
static int csvWrite(KeySet *returned, Key *parentKey, char delim, short useHeader) { FILE *fp; fp = fopen(keyString(parentKey), "w"); if(!fp) { ELEKTRA_SET_ERROR_SET(parentKey); return -1; } keyDel(ksLookup(returned, parentKey, KDB_O_POP)); unsigned long colCounter = 0; unsigned long columns = 0; unsigned long lineCounter = 0; Key *cur; KeySet *toWriteKS; Key *toWrite; while((cur = ksNext(returned)) != NULL) { if(keyRel(parentKey, cur) != 1) continue; if(useHeader) { useHeader = 0; continue; } toWriteKS = ksCut(returned, cur); colCounter = 0; while(1) { toWrite = getKeyByOrderNr(toWriteKS, colCounter); if(!toWrite) break; if(colCounter) fprintf(fp, "%c", delim); ++colCounter; fprintf(fp, "%s", keyString(toWrite)); } ksDel(toWriteKS); fprintf(fp, "\n"); if(columns == 0) { columns = colCounter; } if(colCounter != columns) { ELEKTRA_SET_ERRORF(117, parentKey, "illegal number of columns in line %lu\n", lineCounter); fclose(fp); return -1; } ++lineCounter; } fclose(fp); return 1; }
/** * @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; }
static void test_lookupSingle () { printf ("Test lookup single\n"); Key * specKey = keyNew ("user/abc", KEY_META, "override/#0", "user/something", KEY_END); Key * k = 0; KeySet * ks = ksNew (20, k = keyNew ("user/else", KEY_END), KS_END); succeed_if (ksLookup (ks, specKey, KDB_O_SPEC) == 0, "found wrong key"); keySetMeta (specKey, "fallback/#0", "user/else"); succeed_if (ksLookup (ks, specKey, KDB_O_SPEC) == k, "did not find fallback key"); keySetMeta (specKey, "fallback/#0", ""); succeed_if (ksLookup (ks, specKey, KDB_O_SPEC) == 0, "found wrong key"); keySetMeta (specKey, "override/#0", "user/else"); succeed_if (ksLookup (ks, specKey, KDB_O_SPEC) == k, "did not find override key"); keySetMeta (specKey, "override/#0", ""); succeed_if (ksLookup (ks, specKey, KDB_O_SPEC) == 0, "found wrong key"); keyDel (specKey); ksDel (ks); }
int elektraDbusSet (Plugin * handle, KeySet * returned, Key * parentKey) { KeySet * oldKeys = (KeySet *)elektraPluginGetData (handle); // because elektraLogchangeGet will always be executed before elektraLogchangeSet // we know that oldKeys must exist here! ksRewind (oldKeys); ksRewind (returned); KeySet * addedKeys = ksDup (returned); KeySet * changedKeys = ksNew (0, KS_END); KeySet * removedKeys = ksNew (0, KS_END); Key * k = 0; while ((k = ksNext (oldKeys)) != 0) { Key * p = ksLookup (addedKeys, k, KDB_O_POP); // Note: keyDel not needed, because at least two references exist if (p) { if (keyNeedSync (p)) { ksAppendKey (changedKeys, p); } } else { ksAppendKey (removedKeys, k); } } if (!strncmp (keyName (parentKey), "user", 4)) { announceKeys (addedKeys, "KeyAdded", DBUS_BUS_SESSION); announceKeys (changedKeys, "KeyChanged", DBUS_BUS_SESSION); announceKeys (removedKeys, "KeyDeleted", DBUS_BUS_SESSION); } else if (!strncmp (keyName (parentKey), "system", 6)) { announceKeys (addedKeys, "KeyAdded", DBUS_BUS_SYSTEM); announceKeys (changedKeys, "KeyChanged", DBUS_BUS_SYSTEM); announceKeys (removedKeys, "KeyDeleted", DBUS_BUS_SYSTEM); } ksDel (oldKeys); ksDel (addedKeys); ksDel (changedKeys); ksDel (removedKeys); // for next invocation of elektraLogchangeSet, remember our current keyset elektraPluginSetData (handle, ksDup (returned)); return 1; /* success */ }
static void compareKeySets(KeySet* ks, KeySet* expected) { succeed_if(ksGetSize (expected) == ksGetSize (ks), "KeySet on set does not contain the same amount of keys"); Key* current; ksRewind (expected); while ((current = ksNext (expected))) { Key *key = ksLookup (ks, current, KDB_O_NONE); succeed_if (key, "Expected key was not found in KeySet"); succeed_if (!strcmp(keyString(key), keyString(current)), "Value of key was modified"); } }
static void test_lookupChain () { printf ("Test lookup chain\n"); Key * specKey = keyNew ("user/4", KEY_META, "override/#0", "user/something", KEY_END); Key * k1 = 0; Key * k2 = 0; Key * k3 = 0; Key * k4 = 0; KeySet * ks = ksNew (20, k1 = keyNew ("user/1", KEY_END), k2 = keyNew ("user/2", KEY_END), k3 = keyNew ("user/3", KEY_END), k4 = keyNew ("user/4", KEY_END), KS_END); succeed_if (ksLookup (ks, specKey, KDB_O_SPEC) == k4, "found wrong key"); keySetMeta (specKey, "override/#0", "user/else"); succeed_if (ksLookup (ks, specKey, KDB_O_SPEC) == k4, "found wrong key"); keySetMeta (specKey, "override/#1", "user/wrong"); succeed_if (ksLookup (ks, specKey, KDB_O_SPEC) == k4, "found wrong key"); keySetMeta (specKey, "override/#2", "user/3"); succeed_if (ksLookup (ks, specKey, KDB_O_SPEC) == k3, "did not find override key"); keySetMeta (specKey, "override/#1", "user/2"); succeed_if (ksLookup (ks, specKey, KDB_O_SPEC) == k2, "found wrong key"); keySetMeta (specKey, "override/#0", "user/1"); succeed_if (ksLookup (ks, specKey, KDB_O_SPEC) == k1, "found wrong key"); keyDel (specKey); ksDel (ks); }
void test_checkfile () { printf ("Check file\n"); KeySet * modules = ksNew (0, KS_END); elektraModulesInit (modules, 0); Plugin * plugin = elektraPluginOpen ("resolver", modules, set_pluginconf (), 0); exit_if_fail (plugin, "did not find a resolver"); Key * root = keyNew ("system/elektra/modules", KEY_END); keyAddBaseName (root, plugin->name); KeySet * contract = ksNew (5, KS_END); plugin->kdbGet (plugin, contract, root); keyAddName (root, "/exports/checkfile"); Key * found = ksLookup (contract, root, 0); exit_if_fail (found, "did not find checkfile symbol"); typedef int (*func_t) (const char *); union { func_t f; void * v; } conversation; succeed_if (keyGetBinary (found, &conversation.v, sizeof (conversation)) == sizeof (conversation), "could not get binary"); func_t checkFile = conversation.f; succeed_if (checkFile ("valid") == 1, "valid file not recognised"); succeed_if (checkFile ("/valid") == 0, "valid absolute file not recognised"); succeed_if (checkFile ("/absolute/valid") == 0, "valid absolute file not recognised"); succeed_if (checkFile ("../valid") == -1, "invalid file not recognised"); succeed_if (checkFile ("valid/..") == -1, "invalid file not recognised"); succeed_if (checkFile ("/../valid") == -1, "invalid absolute file not recognised"); succeed_if (checkFile ("/valid/..") == -1, "invalid absolute file not recognised"); succeed_if (checkFile ("very..strict") == -1, "resolver is currently very strict"); succeed_if (checkFile ("very/..strict") == -1, "resolver is currently very strict"); succeed_if (checkFile ("very../strict") == -1, "resolver is currently very strict"); succeed_if (checkFile ("very/../strict") == -1, "resolver is currently very strict"); succeed_if (checkFile ("/") == -1, "invalid absolute file not recognised"); succeed_if (checkFile (".") == -1, "invalid file not recognised"); succeed_if (checkFile ("..") == -1, "invalid file not recognised"); ksDel (contract); keyDel (root); elektraPluginClose (plugin, 0); elektraModulesClose (modules, 0); ksDel (modules); }
static void test_complexInsert (char * source, char * compare) { Key * parentKey = keyNew ("user/tests/ini-write", KEY_VALUE, srcdir_file (source), KEY_END); Key * writeParentKey = keyNew ("user/tests/ini-write", KEY_VALUE, elektraFilename (), KEY_END); KeySet * conf = ksNew (0, KS_END); KeySet * ks = ksNew (30, KS_END); KeySet * appendKS = ksNew (10, keyNew ("user/tests/ini-write/section/subsection", KEY_BINARY, KEY_END), keyNew ("user/tests/ini-write/section/subsection/subkey", KEY_VALUE, "subval", KEY_END), keyNew ("user/tests/ini-write/section/zkey3", KEY_VALUE, "3", KEY_END), KS_END); PLUGIN_OPEN ("ini"); succeed_if (plugin->kdbGet (plugin, ks, parentKey) >= 0, "call to kdbGet was not successful"); keyDel (ksLookup (ks, parentKey, KDB_O_POP)); keyDel (parentKey); ksAppend (ks, appendKS); succeed_if (plugin->kdbSet (plugin, ks, writeParentKey) >= 1, "call to kdbSet was not successful"); succeed_if (compare_line_files (srcdir_file (compare), keyString (writeParentKey)), "files do not match as expected"); keyDel (ksLookup (ks, writeParentKey, KDB_O_POP)); keyDel (writeParentKey); ksDel (appendKS); ksDel (ks); PLUGIN_CLOSE (); }
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; }