Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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);
}
Exemplo n.º 3
0
/**
 * @internal
 * Recursively move all keys in keyset below source to dest.
 *
 * Modifies the keyset.
 *
 * Example:
 * ```
 * moveKeysRecursive("user/plugins/#0", "user/plugins/#1", config);
 * ```
 *
 * @param source Root part to replace
 * @param dest   Destination for keys
 * @param keyset keyset
 */
static void moveKeysRecursive (const char * source, const char * dest, KeySet * keyset)
{
	Key * sourceBaseKey = keyNew (source, KEY_END);
	KeySet * newKeys = ksNew (0, KS_END);

	// Rename keys in keyset
	Key * sourceKey;
	ksRewind (keyset);
	while ((sourceKey = ksNext (keyset)) != NULL)
	{
		// Rename all keys below sourceKey
		if (!keyIsBelowOrSame (sourceBaseKey, sourceKey)) continue;
		Key * destKey = renameKey (source, dest, sourceKey);
		ksAppendKey (newKeys, destKey);
	}

	// Remove source keys from keyset
	KeySet * cut = ksCut (keyset, sourceBaseKey);
	ksDel (cut);

	ksAppend (keyset, newKeys);
	ksDel (newKeys);

	keyDel (sourceBaseKey);
}
Exemplo n.º 4
0
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;
}
Exemplo n.º 5
0
/**
 * @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;
}
Exemplo n.º 6
0
/**
 * @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;
}
Exemplo n.º 7
0
static void validateArray (KeySet * ks, Key * arrayKey, Key * specKey)
{
	Key * tmpArrayParent = keyDup (arrayKey);
	keySetBaseName (tmpArrayParent, 0);
	Key * arrayParent = ksLookup (ks, tmpArrayParent, KDB_O_NONE);
	keyDel (tmpArrayParent);
	if (arrayParent == NULL) return;
	KeySet * ksCopy = ksDup (ks);
	KeySet * subKeys = ksCut (ksCopy, arrayParent);
	Key * cur;
	long validCount = 0;
	while ((cur = ksNext (subKeys)) != NULL)
	{
		if (!keyIsDirectBelow (arrayParent, cur)) continue;
		if (keyBaseName (cur)[0] == '#')
		{
			if (elektraArrayValidateName (cur) == 1)
			{
				++validCount;
				keySetMeta (cur, "spec/internal/valid", "");
			}
			else
			{
				KeySet * invalidCutKS = ksCut (subKeys, cur);
				Key * toMark;
				while ((toMark = ksNext (invalidCutKS)) != NULL)
				{
					if (strcmp (keyName (cur), keyName (toMark))) keySetMeta (toMark, "conflict/invalid", "");
					elektraMetaArrayAdd (arrayParent, "conflict/invalid/hasmember", keyName (toMark));
				}
				ksDel (invalidCutKS);
			}
		}
	}
	ksDel (subKeys);
	ksDel (ksCopy);
	validateArrayRange (arrayParent, validCount, specKey);
}
Exemplo n.º 8
0
int main ()
{
	// clang-format off
//! [cut]
Key * parentKey = keyNew ("system/mountpoint/interest", KEY_END);
KDB * kdb = kdbOpen (parentKey);
KeySet * ks = ksNew (0, KS_END);
kdbGet (kdb, ks, parentKey);
KeySet * returned = ksCut (ks, parentKey);
kdbSet (kdb, ks, parentKey); // all keys below cutpoint are now removed
kdbClose (kdb, parentKey);
//! [cut]
outputKeySet (returned);
outputKeySet (ks);
}
Exemplo n.º 9
0
static void test_ksCut (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];

	// create keyset with some folder 'other' that we will then cut
	KeySet * ks = simpleTestKeySet ();
	KeySet * other = ksNew (10, keyNew ("user/tests/storage/other", KEY_VALUE, "other key", KEY_END),
				keyNew ("user/tests/storage/other/a", KEY_VALUE, "other a value", KEY_END),
				keyNew ("user/tests/storage/other/b", KEY_VALUE, "other b value", KEY_END), KS_END);
	if (ksAppend (ks, other) == -1)
	{
		yield_error ("ksAppend failed");
	}

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

	// now cut the 'other' folder
	Key * cutKey = keyNew ("user/tests/storage/other", KEY_END);
	KeySet * returned = ksCut (ks, cutKey);
	succeed_if (returned, "keyset is empty (does not contain the cut keyset)");

	KeySet * simple = simpleTestKeySet ();
	compare_keyset (simple, ks);
	compare_keyset (other, returned);

	ksDel (other);
	ksDel (returned);
	ksDel (simple);
	keyDel (cutKey);
	keyDel (parentKey);
	ksDel (ks);
	closeStoragePlugin (storagePlugin);
}
Exemplo n.º 10
0
/**Builds a backend out of the configuration supplied
 * from:
 *
@verbatim
system/elektra/mountpoints/<name>
@endverbatim
 *
 * The root key must be like the above example. You do
 * not need to rewind the keyset. But every key must be
 * below the root key.
 *
 * The internal consistency will be checked in this
 * function. If necessary parts are missing, like
 * no plugins, they cant be loaded or similar 0
 * will be returned.
 *
 * ksCut() is perfectly suitable for cutting out the
 * configuration like needed.
 *
 * @note The given KeySet will be deleted within the function,
 * don't use it afterwards.
 *
 * @param elektraConfig the configuration to work with.
 *        It is used to build up this backend.
 * @param modules used to load new modules or get references
 *        to existing one
 * @return a pointer to a freshly allocated backend
 *         this could be the requested backend or a so called
 *         "missing backend".
 * @retval 0 if out of memory
 * @ingroup backend
 */
Backend* elektraBackendOpen(KeySet *elektraConfig, KeySet *modules, Key *errorKey)
{
	Key * cur;
	Key * root;
	KeySet *referencePlugins = 0;
	KeySet *systemConfig = 0;
	int failure = 0;

	referencePlugins = ksNew(0, KS_END);
	ksRewind(elektraConfig);

	root = ksNext (elektraConfig);

	Backend *backend = elektraBackendAllocate();

	while ((cur = ksNext(elektraConfig)) != 0)
	{
		if (keyRel (root, cur) == 1)
		{
			// direct below root key
			KeySet *cut = ksCut (elektraConfig, cur);
			if (!strcmp(keyBaseName(cur), "config"))
			{
				systemConfig = elektraRenameKeys(cut, "system");
				ksDel (cut);
			}
			else if (!strcmp(keyBaseName(cur), "getplugins"))
			{
				if (elektraProcessPlugins(backend->getplugins, modules, referencePlugins,
							cut, systemConfig, errorKey) == -1)
				{
					if (!failure) ELEKTRA_ADD_WARNING(13, errorKey, "elektraProcessPlugins for get failed");
					failure = 1;
				}
			}
			else if (!strcmp(keyBaseName(cur), "mountpoint"))
			{
				backend->mountpoint = keyNew("",
						KEY_VALUE, keyBaseName(root), KEY_END);
				elektraKeySetName(backend->mountpoint, keyString(cur),
						KEY_CASCADING_NAME | KEY_EMPTY_NAME);

				if (!backend->mountpoint)
				{
					if (!failure) ELEKTRA_ADD_WARNINGF(14, errorKey,
						"Could not create mountpoint with name %s and value %s",
						keyString(cur), keyBaseName(root));
					failure = 1;
				}

				keyIncRef(backend->mountpoint);
				ksDel (cut);
			}
			else if (!strcmp(keyBaseName(cur), "setplugins"))
			{
				if (elektraProcessPlugins(backend->setplugins, modules, referencePlugins,
							cut, systemConfig, errorKey) == -1)
				{
					if (!failure) ELEKTRA_ADD_WARNING(15, errorKey, "elektraProcessPlugins for set failed");
					failure = 1;
				}
			}
			else if (!strcmp(keyBaseName(cur), "errorplugins"))
			{
				if (elektraProcessPlugins(backend->errorplugins, modules, referencePlugins,
							cut, systemConfig, errorKey) == -1)
				{
					if (!failure) ELEKTRA_ADD_WARNING(15, errorKey, "elektraProcessPlugins for error failed");
					failure = 1;
				}
			} else {
				// no one cares about that config
				if (!failure) ELEKTRA_ADD_WARNING(16, errorKey, keyBaseName(cur));
				ksDel (cut);
			}
		}
	}

	if (failure)
	{
		Backend *tmpBackend = elektraBackendOpenMissing(backend->mountpoint);
		elektraBackendClose(backend, errorKey);
		backend = tmpBackend;
	}

	ksDel (systemConfig);
	ksDel (elektraConfig);
	ksDel (referencePlugins);

	return backend;
}
Exemplo n.º 11
0
int elektraCsvstorageGet(Plugin *handle, KeySet *returned, Key *parentKey)
{
    if (!strcmp(keyName(parentKey), "system/elektra/modules/csvstorage"))
    {
        KeySet *contract = ksNew (30,
                                  keyNew ("system/elektra/modules/csvstorage",
                                          KEY_VALUE, "csvstorage plugin waits for your orders", KEY_END),
                                  keyNew ("system/elektra/modules/csvstorage/exports", KEY_END),
                                  keyNew ("system/elektra/modules/csvstorage/exports/get",
                                          KEY_FUNC, elektraCsvstorageGet, KEY_END),
                                  keyNew ("system/elektra/modules/csvstorage/exports/set",
                                          KEY_FUNC, elektraCsvstorageSet, KEY_END),
#include ELEKTRA_README(csvstorage)
                                  keyNew ("system/elektra/modules/csvstorage/infos/version",
                                          KEY_VALUE, PLUGINVERSION, KEY_END),
                                  KS_END);
        ksAppend (returned, contract);
        ksDel (contract);

        return 1; /* success */
    }

    KeySet *config = elektraPluginGetConfig(handle);
    Key *delimKey = ksLookupByName(config, "/delimiter", 0);
    char delim = ';';
    if(delimKey)
    {
        const char *delimString = keyString(delimKey);
        delim = delimString[0];
    }

    Key *readHeaderKey = ksLookupByName(config, "/header", 0);
    short useHeader = 0;
    if(readHeaderKey)
    {
        const char *printHeaderString = keyString(readHeaderKey);
        if(!strcmp(printHeaderString, "colname"))
        {
            useHeader = 1;
        }
        else if(!(strcmp(printHeaderString, "skip")))
        {
            useHeader = -1;
        }
        else if(!(strcmp(printHeaderString, "record")))
        {
            useHeader = 0;
        }
        else
        {
            useHeader = 0;
        }
    }
    unsigned long fixColumnCount = 0;
    Key *fixColumnCountKey = ksLookupByName(config, "/columns", 0);
    if(fixColumnCountKey)
    {
        if(keyString(fixColumnCountKey))
        {
            fixColumnCount = atol(keyString(fixColumnCountKey));
        }
    }
    Key *setNamesKey = ksLookupByName(config, "/columns/names", 0);
    char *colNames = NULL;
    if(setNamesKey)
    {
        if(fixColumnCountKey)
        {
            KeySet *namesKS = ksCut(config, setNamesKey);
            unsigned long nrNames = (unsigned long)ksGetSize(namesKS)-1;
            if(nrNames == fixColumnCount)
            {
                colNames = (char *)elektraMalloc(nrNames*sizeof(char *));
                Key *cur;
                char **ptr = (char **)colNames;
                while((cur = ksNext(namesKS)) != NULL)
                {
                    if(!strcmp(keyName(cur), keyName(setNamesKey))) continue;
                    if(!strcmp(keyString(cur), ""))
                        *ptr = NULL;
                    else
                        *ptr = (char *)keyString(cur);
                    ++ptr;
                }
            }
            ksAppend(config, namesKS);
            ksDel(namesKS);
        }
    }
    int nr_keys;
    nr_keys = csvRead(returned, parentKey, delim, useHeader, fixColumnCount, (const char **)colNames);
    if(colNames)
        elektraFree(colNames);
    if (nr_keys == -1) return -1;
    return 1;
}
Exemplo n.º 12
0
/**Builds a backend out of the configuration supplied
 * from:
 *
@verbatim
system/elektra/mountpoints/<name>
@endverbatim
 *
 * The root key must be like the above example. You do
 * not need to rewind the keyset. But every key must be
 * below the root key.
 *
 * The internal consistency will be checked in this
 * function. If necessary parts are missing, like
 * no plugins, they cant be loaded or similar 0
 * will be returned.
 *
 * ksCut() is perfectly suitable for cutting out the
 * configuration like needed.
 *
 * @note The given KeySet will be deleted within the function,
 * don't use it afterwards.
 *
 * @param elektraConfig the configuration to work with.
 *        It is used to build up this backend.
 * @param modules used to load new modules or get references
 *        to existing one
 * @param errorKey the key where an error and warnings are added
 *
 * @return a pointer to a freshly allocated backend
 *         this could be the requested backend or a so called
 *         "missing backend".
 * @retval 0 if out of memory
 * @ingroup backend
 */
Backend* elektraBackendOpen(KeySet *elektraConfig, KeySet *modules, Key *errorKey)
{
	Key * cur;
	KeySet *referencePlugins = 0;
	KeySet *systemConfig = 0;
	int failure = 0;

	referencePlugins = ksNew(0, KS_END);
	ksRewind(elektraConfig);

	Key * root = ksNext (elektraConfig);

	Backend *backend = elektraBackendAllocate();
	if (elektraBackendSetMountpoint(backend, elektraConfig, errorKey) == -1)
	{	// warning already set
		failure = 1;
	}

	while ((cur = ksNext(elektraConfig)) != 0)
	{
		if (keyRel (root, cur) == 1)
		{
			// direct below root key
			KeySet *cut = ksCut (elektraConfig, cur);
			if (!strcmp(keyBaseName(cur), "config"))
			{
				systemConfig = elektraRenameKeys(cut, "system");
				ksDel (cut);
			}
			else if (!strcmp(keyBaseName(cur), "errorplugins"))
			{
				if (elektraProcessPlugins(backend->errorplugins, modules, referencePlugins,
							cut, systemConfig, errorKey) == -1)
				{
					if (!failure) ELEKTRA_ADD_WARNING(15, errorKey, "elektraProcessPlugins for error failed");
					failure = 1;
				}
			}
			else if (!strcmp(keyBaseName(cur), "getplugins"))
			{
				if (elektraProcessPlugins(backend->getplugins, modules, referencePlugins,
							cut, systemConfig, errorKey) == -1)
				{
					if (!failure) ELEKTRA_ADD_WARNING(13, errorKey, "elektraProcessPlugins for get failed");
					failure = 1;
				}
			}
			else if (!strcmp(keyBaseName(cur), "mountpoint"))
			{
				ksDel (cut); // already handled by elektraBackendSetMountpoint
				continue;
			}
			else if (!strcmp(keyBaseName(cur), "setplugins"))
			{
				if (elektraProcessPlugins(backend->setplugins, modules, referencePlugins,
							cut, systemConfig, errorKey) == -1)
				{
					if (!failure) ELEKTRA_ADD_WARNING(15, errorKey, "elektraProcessPlugins for set failed");
					failure = 1;
				}
			} else {
				// no one cares about that config
				if (!failure) ELEKTRA_ADD_WARNING(16, errorKey, keyBaseName(cur));
				ksDel (cut);
			}
		}
	}

	if (failure)
	{
		Backend *tmpBackend = elektraBackendOpenMissing(backend->mountpoint);
		elektraBackendClose(backend, errorKey);
		backend = tmpBackend;
	}

	ksDel (systemConfig);
	ksDel (elektraConfig);
	ksDel (referencePlugins);

	return backend;
}
Exemplo n.º 13
0
/**
 * Load a plugin.
 *
 * The array of plugins must be set to 0.
 * Its length is NR_OF_PLUGINS.
 *
 * systemConfig will only be used, not deleted.
 *
 * @param config the config with the information how the
 *        plugins should be put together
 * @param systemConfig the shared (system) config for the plugins.
 *        Every plugin additional get this config.
 *
 * @retval -1 on failure
 */
int elektraProcessPlugins (Plugin ** plugins, KeySet * modules, KeySet * referencePlugins, KeySet * config, KeySet * systemConfig,
			   Key * errorKey)
{
	Key * root;
	Key * cur;

	ksRewind (config);

	root = ksNext (config);

	while ((cur = ksNext (config)) != 0)
	{
		if (keyRel (root, cur) == 1)
		{
			char * pluginName = 0;
			char * referenceName = 0;
			int pluginNumber = 0;

			Key * key;

			if (elektraProcessPlugin (cur, &pluginNumber, &pluginName, &referenceName, errorKey) == -1)
			{
				elektraFree (pluginName);
				elektraFree (referenceName);
				ksDel (config);
				return -1;
			}


			if (pluginName)
			{
				key = keyDup (cur);
				keyAddBaseName (key, "config");
				KeySet * cutConfig = ksCut (config, key);
				keyDel (key);

				KeySet * pluginConfig = elektraRenameKeys (cutConfig, "user");
				ksDel (cutConfig);
				if (!pluginConfig) return -1;
				ksAppend (pluginConfig, systemConfig);
				ksRewind (pluginConfig); /* TODO: bug ksAppend invalidates cursor */

				/* case 1, we create a new plugin,
				   note that errorKey is not passed here, because it would set error information
				   but we only want a warning instead. */
				plugins[pluginNumber] = elektraPluginOpen (pluginName, modules, pluginConfig, errorKey);
				if (!plugins[pluginNumber])
				{
					ELEKTRA_ADD_WARNING (64, errorKey, pluginName);
					/* Loading plugin did not work */
					elektraFree (pluginName);
					elektraFree (referenceName);
					ksDel (config);
					return -1;
				}

				/* case 2, we label it for later use */
				if (referenceName)
					ksAppendKey (referencePlugins,
						     keyNew (referenceName, KEY_BINARY, KEY_SIZE, sizeof (plugins[pluginNumber]), KEY_VALUE,
							     &plugins[pluginNumber], KEY_END));
			}
			else
			{
				/* case 3, we use an existing plugin */
				Key * lookup = ksLookup (referencePlugins, keyNew (referenceName, KEY_END), KDB_O_DEL);
				if (!lookup)
				{
					ELEKTRA_ADD_WARNING (65, errorKey, referenceName);
					/* Getting a reference plugin at a previous stage did not work.
					Note that this check is necessary, because loading the plugin could
					fail for example at errorplugins and at a later point, for example
					at setplugins it is tried to refer to that.*/
					elektraFree (referenceName);
					ksDel (config);
					return -1;
				}
				plugins[pluginNumber] = *(Plugin **)keyValue (lookup);
				++plugins[pluginNumber]->refcounter;
			}
			elektraFree (pluginName);
			elektraFree (referenceName);
		}
		else
		{
			ELEKTRA_ADD_WARNING (21, errorKey, keyString (cur));
		}
	}

	ksDel (config);
	return 0;
}
Exemplo n.º 14
0
static int listParseConfiguration (Placements * placements, KeySet * config)
{
	Key * cur;
	Key * key = ksLookupByName (config, "/plugins", 0);
	KeySet * cutKS = ksCut (config, key);
	ksRewind (cutKS);
	if (ksGetSize (cutKS) < 2) return 0;
	int rc = 0;
	while ((cur = ksNext (cutKS)) != NULL)
	{
		if (keyRel (key, cur) != 1)
		{
			continue;
		}
		if (keyBaseName (cur)[0] == '#')
		{
			if (strcmp (lastIndex, keyBaseName (cur)) < 0)
			{
				snprintf (lastIndex, ELEKTRA_MAX_ARRAY_SIZE, "%s", keyBaseName (cur));
			}
		}
		Key * sub;
		Key * lookup = keyDup (cur);
		keyAddBaseName (lookup, "placements");
		keyAddBaseName (lookup, "set");
		sub = ksLookup (cutKS, lookup, 0);
		if (sub)
		{
			const char * setString = keyString (sub);
			const char * setStrings[] = { "presetstorage", "presetcleanup", "precommit", "postcommit" };
			SetPlacements setPlacement = preSetStorage;
			while (setPlacement != setEnd)
			{
				if (strstr (setString, setStrings[setPlacement]))
				{
					rc = 1;
					ksAppendKey (placements->setKS[setPlacement], keyDup (cur));
				}
				++setPlacement;
			}
		}
		keySetBaseName (lookup, "get");
		sub = ksLookup (cutKS, lookup, 0);
		if (sub)
		{
			const char * getString = keyString (sub);
			const char * getStrings[] = { "pregetstorage", "postgetstorage", "postgetcleanup" };
			GetPlacements getPlacement = preGetStorage;
			while (getPlacement != getEnd)
			{
				if (strstr (getString, getStrings[getPlacement]))
				{
					rc = 1;
					ksAppendKey (placements->getKS[getPlacement], keyDup (cur));
				}
				++getPlacement;
			}
		}
		keySetBaseName (lookup, "error");
		sub = ksLookup (cutKS, lookup, 0);
		if (sub)
		{
			const char * errString = keyString (sub);
			const char * errStrings[] = { "prerollback", "postrollback" };
			ErrPlacements errPlacement = preRollback;
			while (errPlacement != errEnd)
			{
				if (strstr (errString, errStrings[errPlacement]))
				{
					rc = 1;
					ksAppendKey (placements->errKS[errPlacement], keyDup (cur));
				}
				++errPlacement;
			}
		}
		keyDel (lookup);
	}
	ksDel (cutKS);
	return rc;
}