예제 #1
0
KeySet * doElektraMerge (KeySet * ours, KeySet * theirs, KeySet * base)
{
	printf ("see libelektra-tools for merging"
		" sizes are: %d %d %d\n",
		(int)ksGetSize (ours), (int)ksGetSize (theirs), (int)ksGetSize (base));
	return ksNew (0, KS_END);
}
예제 #2
0
파일: tests.c 프로젝트: intfrr/libelektra
void output_split(Split *split)
{
	for (size_t i=0; i<split->size; ++i)
	{
		if (split->handles[i])
		{
			printf ("split #%zd size: %zd, handle: %p, sync: %d, parent: %s (%s), us: %zd, ss: %zd\n",
				i,
				ksGetSize(split->keysets[i]),
				(void*)split->handles[i],
				split->syncbits[i],
				keyName(split->parents[i]),
				keyString(split->parents[i]),
				split->handles[i]->usersize,
				split->handles[i]->systemsize
				);
		} else {
			printf ("split #%zd, size: %zd, default split, sync: %d\n",
				i,
				ksGetSize(split->keysets[i]),
				split->syncbits[i]
				);
		}
	}
}
예제 #3
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);
}
예제 #4
0
static void test_ksPop (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 = 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");

	KeySet * poppedKeys = ksNew (0, KS_END);
	succeed_if (ksAppendKey (poppedKeys, ksPop (ks)) != -1, "ksAppendKey failed");
	succeed_if (ksAppendKey (poppedKeys, ksPop (ks)) != -1, "ksAppendKey failed");
	succeed_if (ksGetSize (ks) == 1, "ksGetSize after ksPop should be decremented");
	succeed_if (ksAppendKey (poppedKeys, ksPop (ks)) != -1, "ksAppendKey failed");
	succeed_if (ksGetSize (poppedKeys) == 3, "expecting three keys to be in ks");
	succeed_if (ksPop (ks) == 0, "ks should be empty");
	succeed_if (ksAppendKey (poppedKeys, ksPop (ks)) == -1, "ks should be empty, but is not");

	KeySet * test = simpleTestKeySet ();
	compare_keyset (poppedKeys, test);
	ksDel (test);

	ksDel (poppedKeys);
	keyDel (parentKey);
	ksDel (ks);
	closeStoragePlugin (storagePlugin);
}
예제 #5
0
/**
 * Also update sizes after kdbSet() to recognize multiple kdbSet() attempts.
 *
 * @warning cant use the same code with elektraSplitGet because there is
 * no default split part for kdbSet().
 */
int elektraSplitUpdateSize (Split * split)
{
	/* Iterate everything */
	for (size_t i = 0; i < split->size; ++i)
	{
		switch (keyGetNamespace (split->parents[i]))
		{
		case KEY_NS_SPEC:
			split->handles[i]->specsize = ksGetSize (split->keysets[i]);
			break;
		case KEY_NS_DIR:
			split->handles[i]->dirsize = ksGetSize (split->keysets[i]);
			break;
		case KEY_NS_USER:
			split->handles[i]->usersize = ksGetSize (split->keysets[i]);
			break;
		case KEY_NS_SYSTEM:
			split->handles[i]->systemsize = ksGetSize (split->keysets[i]);
			break;
		case KEY_NS_PROC:
		case KEY_NS_EMPTY:
		case KEY_NS_NONE:
		case KEY_NS_META:
		case KEY_NS_CASCADING:
			return -1;
		}
	}
	return 1;
}
예제 #6
0
static void test_ksAppendKey (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 = simpleTestKeySet ();
	ssize_t origSize = ksGetSize (ks);
	succeed_if (plugin->kdbSet (plugin, ks, parentKey) == 1, "kdbSet was not successful");
	succeed_if (plugin->kdbGet (plugin, ks, parentKey) == 1, "kdbGet was not successful");

	ssize_t appendSize = 0;
	Key * toAppend = keyNew (TEST_ROOT_KEY "/my/new/key", KEY_END);

	if ((appendSize = ksAppendKey (ks, toAppend)) == -1)
	{
		yield_error ("ksAppendKey failed");
	}

	succeed_if (appendSize == (origSize + 1), "ksAppendKey after append should be incremented");
	succeed_if (plugin->kdbSet (plugin, ks, parentKey) == 1, "kdbSet was not successful");
	ksDel (ks);
	ks = ksNew (0, KS_END);
	succeed_if (plugin->kdbGet (plugin, ks, parentKey) == 1, "kdbGet was not successful");
	ssize_t returnedSize = ksGetSize (ks);

	succeed_if (returnedSize == (origSize + 1), "ksGetSize after append should be incremented");

	keyDel (parentKey);
	ksDel (ks);
	closeStoragePlugin (storagePlugin);
}
예제 #7
0
static int saveTree (augeas * augeasHandle, KeySet * ks, const char * lensPath, Key * parentKey)
{
	int ret = 0;

	size_t prefixSize = keyGetNameSize (parentKey) - 1;
	size_t arraySize = ksGetSize (ks);
	Key ** keyArray = calloc (ksGetSize (ks), sizeof (Key *));
	ret = elektraKsToMemArray (ks, keyArray);

	if (ret < 0) goto memoryerror;

	qsort (keyArray, arraySize, sizeof (Key *), keyCmpOrderWrapper);

	/* convert the Elektra KeySet to an Augeas tree */
	for (size_t i = 0; i < arraySize; i++)
	{
		Key * key = keyArray[i];
		char * nodeName;
		ret = asprintf (&nodeName, AUGEAS_TREE_ROOT "%s", (keyName (key) + prefixSize));

		if (ret < 0) goto memoryerror;

		aug_set (augeasHandle, nodeName, keyString (key));
		elektraFree (nodeName);
	}

	elektraFree (keyArray);

	/* remove keys not present in the KeySet */
	struct OrphanSearch * data = elektraMalloc (sizeof (struct OrphanSearch));

	if (!data) return -1;

	data->ks = ks;
	data->parentKey = parentKey;

	ret = foreachAugeasNode (augeasHandle, AUGEAS_TREE_ROOT, &removeOrphan, data);

	elektraFree (data);

	/* build the tree */
	ret = aug_text_retrieve (augeasHandle, lensPath, AUGEAS_CONTENT_ROOT, AUGEAS_TREE_ROOT, AUGEAS_OUTPUT_ROOT);

	if (ret < 0)
	{
		/* report the augeas specific error */
		ELEKTRA_SET_ERROR (85, parentKey, getAugeasError (augeasHandle));
	}

	return ret;

memoryerror:
	elektraFree (keyArray);
	ELEKTRA_SET_ERROR (87, parentKey, "Unable to allocate memory while saving the augeas tree");
	return -1;
}
예제 #8
0
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");
	}
}
예제 #9
0
static void test_lookupIndirect ()
{
	printf ("Test lookup by indirect spec\n");

	Key * s;
	Key * p;
	Key * d;
	Key * u;
	Key * y;
	Key * e;
	KeySet * ks =
		ksNew (20, s = keyNew ("spec/abc", KEY_END), p = keyNew ("proc/abc", KEY_END), d = keyNew ("dir/abc", KEY_END),
		       u = keyNew ("user/abc", KEY_END), y = keyNew ("system/abc", KEY_END), e = keyNew ("system/else", KEY_END), KS_END);
	succeed_if (ksGetSize (ks) == 6, "wrong size");

	Key * k = ksLookupByName (ks, "/abc", 0);
	succeed_if (k == p, "did not find proc key");

	keySetMeta (s, "namespace/#0", "no");
	keySetMeta (s, "default", "80");
	k = ksLookupByName (ks, "/abc", 0);
	succeed_if (k != 0, "should find default");
	succeed_if (ksGetSize (ks) == 7, "default key not added");
	succeed_if_same_string (keyString (k), "80");

	Key * k2 = ksLookupByName (ks, "/abc", 0);
	succeed_if (k == k2, "did not get same default");

	keySetMeta (s, "fallback/#0", "/else");
	k = ksLookupByName (ks, "/abc", 0);
	succeed_if (k == e, "did not find else");

	keySetMeta (s, "namespace/#0", "system");
	k = ksLookupByName (ks, "/abc", 0);
	succeed_if (k == y, "did not find system key");

	keySetMeta (s, "namespace/#0", "system");
	keySetMeta (s, "namespace/#1", "user");
	k = ksLookupByName (ks, "/abc", 0);
	succeed_if (k == y, "did not find system key");

	keySetMeta (s, "namespace/#0", "proc");
	keySetMeta (s, "namespace/#1", "user");
	k = ksLookupByName (ks, "/abc", 0);
	succeed_if (k == p, "did not find proc key");

	keySetMeta (s, "override/#0", "/else");
	k = ksLookupByName (ks, "/abc", 0);
	succeed_if (k == e, "did not find override key");

	ksDel (ks);
}
예제 #10
0
파일: augeas.c 프로젝트: beku/libelektra
static int saveTree(augeas* augeasHandle, KeySet* ks, const char* lensPath,
		Key *parentKey)
{
	int ret = 0;

	size_t prefixSize = keyGetNameSize (parentKey) - 1;
	size_t arraySize = ksGetSize (ks);
	Key **keyArray = calloc (ksGetSize(ks), sizeof (Key *));
	ret = elektraKsToMemArray (ks, keyArray);

	if (ret < 0)
	{
		free (keyArray);
		return -1;
	}

	qsort (keyArray, arraySize, sizeof(Key *), keyCmpOrderWrapper);

	/* convert the Elektra KeySet to an Augeas tree */
	for (size_t i = 0; i < arraySize; i++)
	{
		Key *key = keyArray[i];
		char *nodeName;
		asprintf (&nodeName, AUGEAS_TREE_ROOT "%s",
				(keyName (key) + prefixSize));
		aug_set (augeasHandle, nodeName, keyString (key));
		free (nodeName);
	}

	free (keyArray);

	/* remove keys not present in the KeySet */
	struct OrphanSearch *data = malloc (sizeof(struct OrphanSearch));

	if (!data) return -1;

	data->ks = ks;
	data->parentKey = parentKey;

	foreachAugeasNode (augeasHandle, AUGEAS_TREE_ROOT, &removeOrphan, data);

	free (data);

	/* build the tree */
	ret = aug_text_retrieve (augeasHandle, lensPath, AUGEAS_CONTENT_ROOT,
	AUGEAS_TREE_ROOT, AUGEAS_OUTPUT_ROOT);

	return ret;
}
예제 #11
0
/**
 * Does some work after getting of backends is finished.
 *
 * - Update sizes
 * - Removal of wrong keys
 *
 * @pre elektraSplitAppoint() needs to be executed before.
 *
 * - check if keys are in correct backend
 * - remove syncbits
 * - update sizes in the backends
 *
 * @param split the split object to work with
 * @param warningKey postcondition violations are reported here
 * @param handle the handle to preprocess the keys
 * @retval 1 on success
 * @retval -1 if no backend was found for a key or split->parents
 *         has invalid namespace
 * @ingroup split
 */
int elektraSplitGet (Split * split, Key * warningKey, KDB * handle)
{
	int ret = 1;
	/* Dont iterate the default split part */
	const int bypassedSplits = 1;

	for (size_t i = 0; i < split->size - bypassedSplits; ++i)
	{
		if (test_bit (split->syncbits[i], 0))
		{
			/* Dont process keysets which come from the user
			   and not from the backends */
			continue;
		}

/* Update sizes */
#if DEBUG && VERBOSE
		printf ("Update size for %s\n", keyName (split->parents[i]));
#endif
		// first we need postprocessing because that might
		// reduce sizes
		if (elektraSplitPostprocess (split, i, warningKey, handle) == -1) ret = -1;
		// then we can set the size
		if (elektraBackendUpdateSize (split->handles[i], split->parents[i], ksGetSize (split->keysets[i])) == -1) ret = -1;
	}

	return ret;
}
예제 #12
0
static void test_ksToArray ()
{
	KeySet * ks = ksNew (5, keyNew ("user/test1", KEY_END), keyNew ("user/test2", KEY_END), keyNew ("user/test3", KEY_END), KS_END);

	Key ** keyArray = calloc (ksGetSize (ks), sizeof (Key *));
	elektraKsToMemArray (ks, keyArray);

	succeed_if_same_string ("user/test1", keyName (keyArray[0]));
	succeed_if_same_string ("user/test2", keyName (keyArray[1]));
	succeed_if_same_string ("user/test3", keyName (keyArray[2]));

	/* test if cursor is restored */
	ksNext (ks);
	cursor_t cursor = ksGetCursor (ks);
	elektraKsToMemArray (ks, keyArray);

	succeed_if (ksGetCursor (ks) == cursor, "cursor was not restored");

	succeed_if (elektraKsToMemArray (0, keyArray) < 0, "wrong result on null pointer");
	succeed_if (elektraKsToMemArray (ks, 0) < 0, "wrong result on null buffer");
	KeySet * empty = ksNew (0, KS_END);
	succeed_if (elektraKsToMemArray (empty, keyArray) == 0, "wrong result on empty keyset");
	ksDel (empty);

	elektraFree (keyArray);
	ksDel (ks);
}
예제 #13
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);
	}
}
예제 #14
0
void test_structure()
{
	printf ("Test structure of keys returned from uname plugin");

	Key *parentKey = keyNew("user/test/key", KEY_END);
	KeySet *keys = ksNew(0, KS_END);
	KeySet *conf = 0;

	PLUGIN_OPEN("uname");

	succeed_if (plugin->kdbGet(plugin, keys, parentKey) == 1, "could not call kdbGet");

	succeed_if (ksGetSize(keys) == 6, "size not correct");
	succeed_if (ksLookupByName(keys, "user/test/key", 0), "parentkey not found");
	succeed_if (ksLookupByName(keys, "user/test/key/sysname", 0), "sysname key not found");
	succeed_if (ksLookupByName(keys, "user/test/key/nodename", 0), "nodename key not found");
	succeed_if (ksLookupByName(keys, "user/test/key/release", 0), "release key not found");
	succeed_if (ksLookupByName(keys, "user/test/key/version", 0), "version key not found");
	succeed_if (ksLookupByName(keys, "user/test/key/machine", 0), "machine key not found");

	ksDel(keys);
	keyDel(parentKey);

	PLUGIN_CLOSE();
}
예제 #15
0
파일: proposal.c 프로젝트: beku/libelektra
/**
 * @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;
}
예제 #16
0
static void test_lookupDoubleIndirectDefault ()
{
	printf ("Test lookup by double indirect spec with default\n");

	Key * s;
	Key * p;
	Key * u;
	Key * y;
	Key * se;
	Key * pe;
	KeySet * ks =
		ksNew (20, se = keyNew ("spec/first", KEY_END), pe = keyNew ("proc/first", KEY_END), s = keyNew ("spec/abc", KEY_END),
		       p = keyNew ("proc/abc", KEY_END), u = keyNew ("user/abc", KEY_END), y = keyNew ("system/abc", KEY_END), KS_END);
	succeed_if (ksGetSize (ks) == 6, "wrong size");
	keySetMeta (se, "default", "default is ok");
	keySetMeta (s, "default", "default is NOT ok");

	Key * k = ksLookupByName (ks, "/first", 0);
	succeed_if (k == pe, "did not find proc key");

	keySetMeta (se, "namespace/#0", "system");
	k = ksLookupByName (ks, "/first", 0);
	succeed_if_same_string (keyString (k), "default is ok");

	keySetMeta (se, "override/#0", "/abc");
	k = ksLookupByName (ks, "/first", 0);
	succeed_if (k == p, "did not find proc/abc");

	keySetMeta (s, "namespace/#0", "system");
	k = ksLookupByName (ks, "/first", 0);
	succeed_if (k == y, "did not find system key");

	keySetMeta (s, "namespace/#0", "system");
	keySetMeta (s, "namespace/#1", "user");
	k = ksLookupByName (ks, "/first", 0);
	succeed_if (k == y, "did not find system key");

	keySetMeta (s, "namespace/#0", "proc");
	keySetMeta (s, "namespace/#1", "user");
	k = ksLookupByName (ks, "/first", 0);
	succeed_if (k == p, "did not find proc key");

	keySetMeta (s, "namespace/#0", "dir");
	keySetMeta (s, "namespace/#1", 0);
	k = ksLookupByName (ks, "/first", 0);
	succeed_if_same_string (keyString (k), "default is ok");

	keySetMeta (s, "override/#0", "proc/first");
	k = ksLookupByName (ks, "/first", 0);
	succeed_if (k == pe, "did not find override key (double indirect)");

	keySetMeta (s, "override/#0", "dir/first");
	k = ksLookupByName (ks, "/first", 0);
	succeed_if_same_string (keyString (k), "default is ok");

	ksDel (ks);
}
예제 #17
0
/**
 * Gets the size of an array.
 *
 * @param elektra The Elektra instance to use.
 * @param name    The (relative) name of the array.
 * @return the size of the array
 */
size_t elektraArraySize (Elektra * elektra, const char * name)
{
	elektraSetLookupKey (elektra, name);
	KeySet * arrayKeys = elektraArrayGet (elektra->lookupKey, elektra->config);
	size_t size = (size_t) ksGetSize (arrayKeys);
	ksDel (arrayKeys);

	return size;
}
예제 #18
0
파일: proposal.c 프로젝트: beku/libelektra
/**
 * Return all the array keys below the given arrayparent
 * The arrayparent itself is not returned.
 * For example, if user/config/# is an array,
 * user/config is the array parent.
 * Only the direct array keys will be returned. This means
 * that for example user/config/#1/key will not be included,
 * but only user/config/#1.
 *
 * A new keyset will be allocated for the resulting keys.
 * This means that the caller must ksDel the resulting keyset.
 *
 * @param arrayParent the parent of the array to be returned
 * @param keys the keyset containing the array keys.
 *
 * @return a keyset containing the arraykeys (if any)
 * @retval NULL on NULL pointers
 */
KeySet *elektraArrayGet(const Key *arrayParent, KeySet *keys)
{
	if (!arrayParent) return 0;

	if (!keys) return 0;

	KeySet *arrayKeys = ksNew(ksGetSize(keys), KS_END);
	elektraKsFilter(arrayKeys, keys, &arrayFilter, (void *)arrayParent);
	return arrayKeys;
}
예제 #19
0
파일: kdb.c 프로젝트: KurtMi/libelektra
/**
 * @brief Bootstrap, first phase with fallback
 * @internal
 *
 * @param handle already allocated, but without defaultBackend
 * @param [out] keys for bootstrapping
 * @param errorKey key to add errors too
 *
 * @retval -1 failure: cannot initialize defaultBackend
 * @retval 0 warning: could not get initial config
 * @retval 1 success
 * @retval 2 success in fallback mode
 */
int elektraOpenBootstrap (KDB * handle, KeySet * keys, Key * errorKey)
{
	handle->defaultBackend = backendOpenDefault (handle->modules, KDB_DB_INIT, errorKey);
	if (!handle->defaultBackend) return -1;

	handle->split = splitNew ();
	splitAppend (handle->split, handle->defaultBackend, keyNew (KDB_SYSTEM_ELEKTRA, KEY_END), 2);

	keySetName (errorKey, KDB_SYSTEM_ELEKTRA);
	keySetString (errorKey, "kdbOpen(): get");

	int funret = 1;
	int ret = kdbGet (handle, keys, errorKey);
	int fallbackret = 0;
	if (ret == 0 || ret == -1)
	{
		// could not get KDB_DB_INIT, try KDB_DB_FILE
		// first cleanup:
		ksClear (keys);
		backendClose (handle->defaultBackend, errorKey);
		splitDel (handle->split);

		// then create new setup:
		handle->defaultBackend = backendOpenDefault (handle->modules, KDB_DB_FILE, errorKey);
		if (!handle->defaultBackend)
		{
			elektraRemoveMetaData (errorKey, "error"); // fix errors from kdbGet()
			return -1;
		}
		handle->split = splitNew ();
		splitAppend (handle->split, handle->defaultBackend, keyNew (KDB_SYSTEM_ELEKTRA, KEY_END), 2);

		keySetName (errorKey, KDB_SYSTEM_ELEKTRA);
		keySetString (errorKey, "kdbOpen(): get fallback");
		fallbackret = kdbGet (handle, keys, errorKey);
		keySetName (errorKey, "system/elektra/mountpoints");

		KeySet * cutKeys = ksCut (keys, errorKey);
		if (fallbackret == 1 && ksGetSize (cutKeys) != 0)
		{
			funret = 2;
		}
		ksAppend (keys, cutKeys);
		ksDel (cutKeys);
	}

	if (ret == -1 && fallbackret == -1)
	{
		funret = 0;
	}

	elektraRemoveMetaData (errorKey, "error"); // fix errors from kdbGet()
	return funret;
}
예제 #20
0
static void test_ksGetSize (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 = simpleTestKeySet ();
	ssize_t origSize = ksGetSize (ks);
	succeed_if (origSize > 0, "ks was empty before kdbSet");
	succeed_if (plugin->kdbSet (plugin, ks, parentKey) == 1, "kdbSet was not successful");

	ksDel (ks);
	ks = ksNew (0, KS_END);
	succeed_if (plugin->kdbGet (plugin, ks, parentKey) == 1, "kdbGet was not successful");
	ssize_t returnedSize = ksGetSize (ks);
	succeed_if (origSize == returnedSize, "ksGetSize before and after kdbSet, kdbGet differ");

	keyDel (parentKey);
	ksDel (ks);
	closeStoragePlugin (storagePlugin);
}
예제 #21
0
// test simple variable passing
static void test_variable_passing (void)
{
	printf ("Testing simple variable passing...\n");

	KeySet * conf = ksNew (1, keyNew ("user/script", KEY_VALUE, srcdir_file ("lua/lua_plugin.lua"), KEY_END),
			       keyNew ("user/print", KEY_END), KS_END);
	PLUGIN_OPEN ("lua");

	Key * parentKey = keyNew ("user/from_c", KEY_END);
	KeySet * ks = ksNew (0, KS_END);
	succeed_if (plugin->kdbGet (plugin, ks, parentKey) >= 1, "call to kdbGet was not successful");
	succeed_if (ksGetSize (ks) == 1, "keyset size is still 0");
	succeed_if (ksGetSize (ks) == 1 && !strcmp (keyName (ksHead (ks)), "user/from_lua"), "key in keyset has wrong name");
	succeed_if (output_warnings (parentKey), "warnings in kdbOpen");
	succeed_if (output_error (parentKey), "errors in kdbOpen");

	ksDel (ks);
	keyDel (parentKey);

	PLUGIN_CLOSE ();
}
예제 #22
0
/* The KeySet MUST be sorted alphabetically (or at least ascending
 * by the length of keynames) for this function to work
 */
static Key * findNearestParent (Key * key, KeySet * ks)
{
    Key * current;
    ksSetCursor (ks, ksGetSize (ks) - 1);
    while ((current = ksPrev (ks)) != 0)
    {
        if (keyIsBelow (current, key))
        {
            return current;
        }
    }

    return 0;
}
예제 #23
0
static void test_mmap_empty_after_clear (const char * tmpFile)
{
	Key * parentKey = keyNew (TEST_ROOT_KEY, KEY_VALUE, tmpFile, KEY_END);
	KeySet * conf = ksNew (0, KS_END);
	PLUGIN_OPEN ("mmapstorage");
	KeySet * returned = ksNew (0, KS_END);

	succeed_if (plugin->kdbGet (plugin, returned, parentKey) == 1, "kdbGet was not successful");

	succeed_if (ksGetSize (returned) == 0, "KeySet not empty after clear (or nullptr)");

	ksDel (returned);
	keyDel (parentKey);
	PLUGIN_CLOSE ();
}
예제 #24
0
//! [f]
void f (KeySet * iterator, KeySet * lookup)
{
	KeySet * append = ksNew (ksGetSize (lookup), KS_END);
	Key * key;
	Key * current;

	ksRewind (iterator);
	while ((current = ksNext (iterator)))
	{
		key = ksLookup (lookup, current, KDB_O_POP);
		// do something...
		ksAppendKey (append, key); // now append it to append, not lookup!
		keyDel (key);		   // make sure to ALWAYS delete poped keys.
	}
	ksAppend (lookup, append);
	// now lookup needs to be sorted only once, append never
	ksDel (append);
}
예제 #25
0
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);
}
예제 #26
0
파일: c.c 프로젝트: sanssecours/libelektra
/**
 * Generate a C-Style keyset and stream it.
 *
 * This keyset can be used to include as c-code for
 * applikations using elektra.
 *
 * The options takes the same options as kdbGet()
 * and kdbSet().
 *
 * @param ks the keyset to work with
 * @param stream the file pointer where to send the stream
 * @param options which keys not to output
 * @retval 1 on success
 * @ingroup stream
 */
int ksGenerate (const KeySet * ks, FILE * stream, option_t options)
{
	Key * key;
	KeySet * cks = ksDup (ks);

	ksRewind (cks);

	fprintf (stream, "ksNew (%d,\n", (int) ksGetSize (cks));
	while ((key = ksNext (cks)) != 0)
	{
		if (options & KDB_O_INACTIVE)
			if (key && keyIsInactive (key)) continue;

		keyGenerate (key, stream, options);
		fprintf (stream, ",\n");
	}
	fprintf (stream, "\tKS_END);\n");

	ksDel (cks);
	return 1;
}
예제 #27
0
파일: stream.c 프로젝트: tryge/libelektra
/**
 * Output all information of a keyset.
 *
 * The format is not very strict and only intend to be read
 * by human eyes for debugging purposes. Don't rely on the
 * format in your applications.
 *
 * Keys are printed line per line with keyOutput().
 *
 * The same options as keyOutput() are taken and passed
 * to them.
 *
 * Additional KDB_O_HEADER will print the number of keys
 * as first line.
 *
 * @param ks the keyset to work with
 * @param stream the file pointer where to send the stream
 * @param options
 * @see keyOutput()
 * @retval 1 on success
 * @retval -1 on allocation errors
 * @ingroup stream
 */
int ksOutput(const KeySet *ks, FILE *stream, option_t options)
{
	Key	*key;
	KeySet *cks = ksDup (ks);
	size_t size = 0;

	ksRewind (cks);

	if (KDB_O_HEADER & options) {
		fprintf(stream,"Output keyset of size %d\n", (int)ksGetSize(cks)); 
	}
	while ( (key = ksNext(cks)) != NULL)
	{
		if (options & KDB_O_SHOWINDICES) fprintf(stream, "[%d] ", (int)size);
		keyOutput (key,stream,options);
		size ++;
	}

	ksDel (cks);
	return 1;
}
예제 #28
0
static void test_getArray (void)
{
	printf ("Test get array");

	KeySet * keys =
		ksNew (10, keyNew ("user/test/key1", KEY_END), keyNew ("user/test/key2", KEY_END), keyNew ("user/test/array", KEY_END),
		       keyNew ("user/test/array/#0", KEY_END), keyNew ("user/test/array/#0/below", KEY_END),
		       keyNew ("user/test/array/#1", KEY_END), keyNew ("user/test/yetanotherkey", KEY_END), KS_END);

	Key * arrayParent = keyNew ("user/test/array", KEY_END);
	KeySet * array = elektraArrayGet (arrayParent, keys);

	succeed_if (array, "The getarray function did not return a proper keyset");
	succeed_if (ksGetSize (array) == 2, "the array contains a wrong number of elements");
	succeed_if (ksLookupByName (array, "user/test/array/#0", KDB_O_NONE), "the array does not contain #0");
	succeed_if (ksLookupByName (array, "user/test/array/#1", KDB_O_NONE), "the array does not contain #1");

	keyDel (arrayParent);
	ksDel (array);
	ksDel (keys);
}
예제 #29
0
/**
 * Builds an array of pointers to the keys in the supplied keyset.
 * The keys are not copied, calling keyDel may remove them from
 * the keyset.
 *
 * The size of the buffer can be easily allocated via ksGetSize. Example:
 * @code
 * KeySet *ks = somekeyset;
 * Key **keyArray = calloc (ksGetSize(ks), sizeof (Key *));
 * elektraKsToMemArray (ks, keyArray);
 * ... work with the array ...
 * elektraFree (keyArray);
 * @endcode
 *
 * @param ks the keyset object to work with
 * @param buffer the buffer to put the result into
 * @return the number of elements in the array if successful
 * @return a negative number on null pointers or if an error occurred
 */
int elektraKsToMemArray (KeySet * ks, Key ** buffer)
{
	if (!ks) return -1;
	if (!buffer) return -1;

	/* clear the received buffer */
	memset (buffer, 0, ksGetSize (ks) * sizeof (Key *));

	cursor_t cursor = ksGetCursor (ks);
	ksRewind (ks);
	size_t idx = 0;

	Key * key;
	while ((key = ksNext (ks)) != 0)
	{
		buffer[idx] = key;
		++idx;
	}
	ksSetCursor (ks, cursor);

	return idx;
}
예제 #30
0
static void test_revmoreiterate()
{
	printf ("Test revmoreiterate trie\n");

	for (int i=0; i<5; ++i)
	{

	Trie *trie = 0;
	switch (i)
	{
	case 0:
		trie = test_insert (trie, "user/tests", "tests");
		trie = test_insert (trie, "user/tests/hosts", "hosts");
		trie = test_insert (trie, "user/tests/hosts/below", "below");
		trie = test_insert (trie, "system/tests", "systests");
		trie = test_insert (trie, "system/tests/hosts", "syshosts");
		trie = test_insert (trie, "system/tests/hosts/below", "sysbelow");
		trie = test_insert (trie, "system", "system");
		trie = test_insert (trie, "user", "user");
		break;
	case 1:
		trie = test_insert (trie, "system/tests/hosts", "syshosts");
		trie = test_insert (trie, "system", "system");
		trie = test_insert (trie, "user/tests", "tests");
		trie = test_insert (trie, "user/tests/hosts", "hosts");
		trie = test_insert (trie, "user/tests/hosts/below", "below");
		trie = test_insert (trie, "system/tests", "systests");
		trie = test_insert (trie, "user", "user");
		trie = test_insert (trie, "system/tests/hosts/below", "sysbelow");
		break;
	case 2:
		trie = test_insert (trie, "system/tests/hosts/below", "sysbelow");
		trie = test_insert (trie, "system/tests/hosts", "syshosts");
		trie = test_insert (trie, "user/tests/hosts/below", "below");
		trie = test_insert (trie, "user/tests/hosts", "hosts");
		trie = test_insert (trie, "user/tests", "tests");
		trie = test_insert (trie, "user", "user");
		trie = test_insert (trie, "system/tests", "systests");
		trie = test_insert (trie, "system", "system");
		break;
	case 3:
		trie = test_insert (trie, "user/tests/hosts/below", "below");
		trie = test_insert (trie, "user/tests/hosts", "hosts");
		trie = test_insert (trie, "user/tests", "tests");
		trie = test_insert (trie, "user", "user");
		trie = test_insert (trie, "system/tests/hosts/below", "sysbelow");
		trie = test_insert (trie, "system/tests/hosts", "syshosts");
		trie = test_insert (trie, "system/tests", "systests");
		trie = test_insert (trie, "system", "system");
		break;
	case 4:
		trie = test_insert (trie, "system/tests/hosts/below", "sysbelow");
		trie = test_insert (trie, "system/tests/hosts", "syshosts");
		trie = test_insert (trie, "system/tests", "systests");
		trie = test_insert (trie, "system", "system");
		trie = test_insert (trie, "user/tests/hosts/below", "below");
		trie = test_insert (trie, "user/tests/hosts", "hosts");
		trie = test_insert (trie, "user/tests", "tests");
		trie = test_insert (trie, "user", "user");
		break;
	}

	KeySet *mps = set_mountpoints();

	exit_if_fail (trie, "trie was not build up successfully");

	Key *searchKey = keyNew(0);

	keySetName(searchKey, "user");
	Backend *backend = elektraTrieLookup(trie, searchKey);
	succeed_if (backend, "there should be a backend");
	compare_key(backend->mountpoint, ksLookupByName(mps, "user",0));
	// printf ("backend: %p\n", (void*)backend);


	keySetName(searchKey, "user/tests/hosts/other/below");
	Backend *b2 = elektraTrieLookup(trie, searchKey);
	succeed_if (b2, "there should be a backend");
	compare_key(b2->mountpoint, ksLookupByName(mps, "user/tests/hosts",0));
	// printf ("b2: %p\n", (void*)b2);


	keySetName(searchKey, "user/tests/hosts/other/deep/below");
	b2 = elektraTrieLookup(trie, searchKey);
	succeed_if (b2, "there should be a backend");
	compare_key(b2->mountpoint, ksLookupByName(mps, "user/tests/hosts",0));


	keySetName(searchKey, "user/tests/hosts/below");
	Backend *b3 = elektraTrieLookup(trie, searchKey);
	succeed_if (b3, "there should be a backend");
	compare_key(b3->mountpoint, ksLookupByName(mps, "user/tests/hosts/below",0));
	backend = b3;
	// printf ("b3: %p\n", (void*)b3);


	keySetName(searchKey, "user/tests/hosts/below/other/deep/below");
	b2 = elektraTrieLookup(trie, searchKey);
	succeed_if (b3, "there should be a backend");
	compare_key(b3->mountpoint, ksLookupByName(mps, "user/tests/hosts/below",0));

	keySetName(searchKey, "system");
	backend = elektraTrieLookup(trie, searchKey);
	succeed_if (backend, "there should be a backend");
	compare_key(backend->mountpoint, ksLookupByName(mps, "system",0));
	// printf ("backend: %p\n", (void*)backend);


	keySetName(searchKey, "system/tests/hosts/other/below");
	b2 = elektraTrieLookup(trie, searchKey);
	succeed_if (b2, "there should be a backend");
	compare_key(b2->mountpoint, ksLookupByName(mps, "system/tests/hosts",0));
	// printf ("b2: %p\n", (void*)b2);


	keySetName(searchKey, "system/tests/hosts/other/deep/below");
	b2 = elektraTrieLookup(trie, searchKey);
	succeed_if (b2, "there should be a backend");
	compare_key(b2->mountpoint, ksLookupByName(mps, "system/tests/hosts",0));


	keySetName(searchKey, "system/tests/hosts/below");
	b3 = elektraTrieLookup(trie, searchKey);
	succeed_if (b3, "there should be a backend");
	compare_key(b3->mountpoint, ksLookupByName(mps, "system/tests/hosts/below",0));
	backend = b3;
	// printf ("b3: %p\n", (void*)b3);


	keySetName(searchKey, "system/tests/hosts/below/other/deep/below");
	b2 = elektraTrieLookup(trie, searchKey);
	succeed_if (b3, "there should be a backend");
	compare_key(b3->mountpoint, ksLookupByName(mps, "system/tests/hosts/below",0));

	/*
	printf ("---------\n");
	output_trie(trie);
	*/

	KeySet *mps_cmp = ksNew(0, KS_END);
	collect_mountpoints(trie, mps_cmp);
	succeed_if (ksGetSize(mps_cmp) == 8, "size should be 8");
	compare_keyset(mps, mps_cmp);

	ksDel (mps_cmp);
	ksDel (mps);

	elektraTrieClose(trie, 0);
	keyDel (searchKey);

	} // end for
}