Exemplo n.º 1
0
/**
 * @internal
 * Call kdbGet if there are registrations below the changed key.
 *
 * On kdbGet this plugin implicitly updates registered keys.
 *
 * @see ElektraNotificationChangeCallback (kdbnotificationinternal.h)
 * @param key     changed key
 * @param context callback context
 */
void elektraInternalnotificationDoUpdate (Key * changedKey, ElektraNotificationCallbackContext * context)
{
	ELEKTRA_NOT_NULL (changedKey);
	ELEKTRA_NOT_NULL (context);

	Plugin * plugin = context->notificationPlugin;

	PluginState * pluginState = elektraPluginGetData (plugin);
	ELEKTRA_NOT_NULL (pluginState);

	int kdbChanged = 0;
	KeyRegistration * keyRegistration = pluginState->head;
	while (keyRegistration != NULL)
	{
		Key * registeredKey = keyNew (keyRegistration->name, KEY_END);

		// check if registered key is same or below changed/commit key
		kdbChanged |= checkKeyIsBelowOrSame (changedKey, registeredKey);

		if (keyRegistration->sameOrBelow)
		{
			// check if registered key is also above changed/commit key
			kdbChanged |= checkKeyIsBelowOrSame (registeredKey, changedKey);
		}

		keyRegistration = keyRegistration->next;
		keyDel (registeredKey);
	}

	if (kdbChanged)
	{
		context->kdbUpdate (context->kdb, changedKey);
	}
	keyDel (changedKey);
}
Exemplo n.º 2
0
/**
 * @internal
 * Unmount global plugin at run-time.
 *
 * Removes a plugin at all placements.
 * Undos `mountGlobalPlugin()`.
 *
 * @param  kdb    KDB handle
 * @param  plugin Plugin handle
 * @retval 0 on errors
 * @retval 1 on success
 */
static int unmountGlobalPlugin (KDB * kdb, Plugin * plugin)
{
	ELEKTRA_NOT_NULL (kdb);
	ELEKTRA_NOT_NULL (plugin);

	char * placementList = getPluginPlacementList (plugin);

	// Parse plament list (contains placements from README.md seperated by
	// whitespace)
	char * placement = strtok (placementList, " ");
	while (placement != NULL)
	{
		// Convert placement name to internal index
		int placementIndex = placementToPosition (placement);
		if (placementIndex == -1)
		{
			elektraFree (placementList);
			return 0;
		}

		if (kdb->globalPlugins[placementIndex][MAXONCE] == plugin)
		{
			// Remove from direct placement as global plugin
			kdb->globalPlugins[placementIndex][MAXONCE] = NULL;
		}
		else
		{
			Plugin * pluginAtPlacement = kdb->globalPlugins[placementIndex][MAXONCE];
			// Add plugin to list plugin
			if (strcmp (pluginAtPlacement->name, "list") == 0)
			{
				ELEKTRA_LOG_DEBUG (
					"required position %s/maxonce taken by list plugin, "
					"removing plugin",
					placement);
				int result = listRemovePlugin (pluginAtPlacement, plugin);
				if (!result)
				{
					ELEKTRA_LOG_WARNING ("could not remove plugin from list plugin at position %s/maxonce", placement);
					elektraFree (placementList);
					return 0;
				}
			}
			else
			{
				ELEKTRA_LOG_WARNING (
					"required position %s/maxonce taken by plugin %s, "
					"should be either list or plugin!",
					placement, pluginAtPlacement->name);
			}
		}

		// Process next placement in list
		placement = strtok (NULL, " ");
	}

	elektraFree (placementList);

	return 1;
}
Exemplo n.º 3
0
/**
 * @see ElektraNotificationOpenNotification (kdbnotificationinternal.h)
 */
void elektraZeroMqRecvOpenNotification (Plugin * handle, KeySet * parameters)
{
	ELEKTRA_NOT_NULL (handle);
	ElektraZeroMqRecvPluginData * pluginData = elektraPluginGetData (handle);
	ELEKTRA_NOT_NULL (pluginData);

	ElektraNotificationCallback callback;
	Key * callbackKey = ksLookupByName (parameters, "/callback", 0);
	ELEKTRA_NOT_NULL (callbackKey);
	callback = *(ElektraNotificationCallback *) keyValue (callbackKey);

	ElektraNotificationCallbackContext * context;
	Key * contextKey = ksLookupByName (parameters, "/context", 0);
	if (contextKey != NULL)
	{
		context = *(ElektraNotificationCallbackContext **) keyValue (contextKey);
	}
	else
	{
		context = NULL;
	}

	pluginData->notificationCallback = callback;
	pluginData->notificationContext = context;

	// init dbus connections
	if (pluginData->ioBinding)
	{
		elektraZeroMqRecvSetup (pluginData);
	}
	else
	{
		ELEKTRA_LOG_DEBUG ("no I/O binding present. plugin in noop mode");
	}
}
Exemplo n.º 4
0
static void pluginsOpenNotification (KDB * kdb, ElektraNotificationCallback callback, ElektraNotificationCallbackContext * context)
{
	ELEKTRA_NOT_NULL (kdb);
	ELEKTRA_NOT_NULL (callback);

	KeySet * parameters = ksNew (2, keyNew ("/callback", KEY_FUNC, callback, KEY_END),
				     keyNew ("/context", KEY_BINARY, KEY_SIZE, sizeof (context), KEY_VALUE, &context, KEY_END), KS_END);

	// iterate over global plugins
	for (int positionIndex = 0; positionIndex < NR_GLOBAL_POSITIONS; positionIndex++)
	{
		for (int subPositionIndex = 0; subPositionIndex < NR_GLOBAL_SUBPOSITIONS; subPositionIndex++)
		{
			Plugin * plugin = kdb->globalPlugins[positionIndex][subPositionIndex];
			if (!plugin)
			{
				continue;
			}


			elektraDeferredCall (plugin, "openNotification", parameters);
		}
	}

	ksDel (parameters);
}
Exemplo n.º 5
0
/**
 * @internal
 * Global mount given plugin at run-time.
 *
 * Reads placements from the plugin directly inserts the plugin.
 * Also supports adding itself to the list plugin at run-time if present
 * at requested global placement.
 *
 * @param  kdb    KDB handle
 * @param  plugin Plugin handle
 * @retval 0 on errors
 * @retval 1 on success
 */
static int mountGlobalPlugin (KDB * kdb, Plugin * plugin)
{
	ELEKTRA_NOT_NULL (kdb);
	ELEKTRA_NOT_NULL (plugin);

	char * placementList = getPluginPlacementList (plugin);

	// Parse plament list (contains placements from README.md seperated by
	// whitespace)
	char * placement = strtok (placementList, " ");
	while (placement != NULL)
	{
		// Convert placement name to internal index
		int placementIndex = placementToPosition (placement);
		if (placementIndex == -1)
		{
			elektraFree (placementList);
			return 0;
		}

		if (kdb->globalPlugins[placementIndex][MAXONCE] == NULL)
		{
			// Insert directly as global plugin
			kdb->globalPlugins[placementIndex][MAXONCE] = plugin;
		}
		else
		{
			Plugin * pluginAtPlacement = kdb->globalPlugins[placementIndex][MAXONCE];
			// Add plugin to list plugin
			if (strcmp (pluginAtPlacement->name, "list") == 0)
			{
				ELEKTRA_LOG_DEBUG ("required position %s/maxonce taken by list plugin, adding plugin", placement);
				int result = listAddPlugin (pluginAtPlacement, plugin, placement);
				if (!result)
				{
					ELEKTRA_LOG_WARNING ("could not add plugin to list plugin at position %s/maxonce", placement);
					elektraFree (placementList);
					return 0;
				}
			}
			else
			{
				// cannot manually add list module here. configuration is broken:
				// the list module needs to be mounted in every position to keep track
				// of the current position
				ELEKTRA_LOG_WARNING ("required position %s/maxonce taken by plugin %s, aborting!", placement,
						     pluginAtPlacement->name);
				elektraFree (placementList);
				return 0;
			}
		}

		// Process next placement in list
		placement = strtok (NULL, " ");
	}

	elektraFree (placementList);

	return 1;
}
Exemplo n.º 6
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.º 7
0
/**
 * @see kdbnotificationinternal.h ::ElektraNotificationSetConversionErrorCallback
 */
static void elektraInternalnotificationSetConversionErrorCallback (Plugin * handle, ElektraNotificationConversionErrorCallback callback,
								   void * context)
{
	ELEKTRA_NOT_NULL (handle);
	ELEKTRA_NOT_NULL (callback);
	PluginState * data = elektraPluginGetData (handle);
	ELEKTRA_NOT_NULL (data);

	data->conversionErrorCallback = callback;
	data->conversionErrorCallbackContext = context;
}
Exemplo n.º 8
0
/**
 * @see ElektraIoPluginSetBinding (kdbioplugin.h)
 */
void elektraZeroMqRecvSetIoBinding (Plugin * handle, KeySet * parameters)
{
	ELEKTRA_NOT_NULL (handle);
	ELEKTRA_NOT_NULL (parameters);
	ElektraZeroMqRecvPluginData * data = elektraPluginGetData (handle);
	ELEKTRA_NOT_NULL (data);

	Key * ioBindingKey = ksLookupByName (parameters, "/ioBinding", 0);
	ELEKTRA_NOT_NULL (ioBindingKey);
	ElektraIoInterface * binding = *(ElektraIoInterface **) keyValue (ioBindingKey);

	data->ioBinding = binding;
}
Exemplo n.º 9
0
/**
 * @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;
}
Exemplo n.º 10
0
/**
 * @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;
}
Exemplo n.º 11
0
/**
 * @internal
 * Get notification plugin from kdb.
 *
 * @param  kdb KDB handle
 * @return     Notification plugin handle or NULL if not present
 */
static Plugin * getNotificationPlugin (KDB * kdb)
{
	ELEKTRA_NOT_NULL (kdb);

	if (kdb->notificationPlugin)
	{
		return kdb->notificationPlugin;
	}
	else
	{
		ELEKTRA_LOG_WARNING (
			"notificationPlugin not set. use "
			"elektraNotificationOpen before calling other "
			"elektraNotification-functions");
		return NULL;
	}
}
Exemplo n.º 12
0
static void pluginsCloseNotification (KDB * kdb)
{
	ELEKTRA_NOT_NULL (kdb);

	// iterate over global plugins
	for (int positionIndex = 0; positionIndex < NR_GLOBAL_POSITIONS; positionIndex++)
	{
		for (int subPositionIndex = 0; subPositionIndex < NR_GLOBAL_SUBPOSITIONS; subPositionIndex++)
		{
			Plugin * plugin = kdb->globalPlugins[positionIndex][subPositionIndex];
			if (!plugin)
			{
				continue;
			}

			elektraDeferredCall (plugin, "closeNotification", NULL);
		}
	}
}
Exemplo n.º 13
0
/**
 * @internal
 * Unload plugin by plugin handle.
 *
 * @param  plugin Plugin handle
 * @retval 0 on error
 * @retval 1 on success
 */
static int unloadPlugin (Plugin * plugin)
{
	ELEKTRA_NOT_NULL (plugin);
	Key * errorKey = keyNew (0);
	int result = elektraPluginClose (plugin, errorKey);

	int hasError = keyGetMeta (errorKey, "error") != NULL;
	keyDel (errorKey);

	if (!result || hasError)
	{
		ELEKTRA_LOG_WARNING ("elektraPluginClose failed: result=%d", result);
		return 0;
	}
	else
	{
		return 1;
	}
}