Esempio n. 1
0
int elektraSpecloadOpen (Plugin * handle, Key * errorKey)
{
	Specload * specload = elektraMalloc (sizeof (Specload));

	KeySet * conf = elektraPluginGetConfig (handle);
	if (ksLookupByName (conf, "system/module", 0) != NULL || ksLookupByName (conf, "system/sendspec", 0) != NULL)
	{
		elektraFree (specload);
		return ELEKTRA_PLUGIN_STATUS_SUCCESS;
	}

	if (!getAppAndArgs (conf, &specload->app, &specload->argv, errorKey))
	{
		elektraFree (specload);
		return ELEKTRA_PLUGIN_STATUS_ERROR;
	}

	specload->quickDumpConfig = ksNew (0, KS_END);
	specload->quickDump = elektraInvokeOpen ("quickdump", specload->quickDumpConfig, errorKey);

	if (!specload->quickDump)
	{
		elektraFree (specload);
		return ELEKTRA_PLUGIN_STATUS_ERROR;
	}

	elektraPluginSetData (handle, specload);

	return ELEKTRA_PLUGIN_STATUS_SUCCESS;
}
/**
 * Checks whether specload mode was invoked and if so, sends the specification over stdout
 * in the format expected by specload.
 *
 * You MUST not output anything to stdout before invoking this function. Ideally invoking this
 * is the first thing you do in your main()-function.
 *
 * This function will ONLY RETURN, if specload mode was NOT invoked. Otherwise it will call `exit()`.
 *
 * @param argc pass the value of argc from main
 * @param argv pass the value of argv from main
 */
void specloadCheck (int argc, const char ** argv)
{
	if (argc != 2 || strcmp (argv[1], "--elektra-spec") != 0)
	{
		return;
	}

	KeySet * spec = ksNew (6,
	keyNew("", KEY_META, "mountpoint", "tests_gen_elektra_context.ini", KEY_END),
	keyNew ("/mydouble", KEY_VALUE, "0.0", KEY_META, "default", "0.0", KEY_META, "type", "double", KEY_END),
	keyNew ("/myfloatarray/#", KEY_VALUE, "0.0", KEY_META, "default", "0.0", KEY_META, "type", "float", KEY_END),
	keyNew ("/myint", KEY_VALUE, "0", KEY_META, "default", "0", KEY_META, "type", "long", KEY_END),
	keyNew ("/mystring", KEY_META, "default", "", KEY_META, "type", "string", KEY_END),
	keyNew ("/print", KEY_VALUE, "0", KEY_META, "default", "0", KEY_META, "type", "boolean", KEY_END),
	KS_END);
;

	Key * parentKey = keyNew ("spec/tests/script/gen/elektra/simple", KEY_END);

	KeySet * specloadConf = ksNew (1, keyNew ("system/sendspec", KEY_END), KS_END);
	ElektraInvokeHandle * specload = elektraInvokeOpen ("specload", specloadConf, parentKey);

	int result = elektraInvoke2Args (specload, "sendspec", spec, parentKey);

	elektraInvokeClose (specload, parentKey);
	keyDel (parentKey);
	ksDel (specloadConf);
	ksDel (spec);

	exit (result == ELEKTRA_PLUGIN_STATUS_SUCCESS ? EXIT_SUCCESS : EXIT_FAILURE);
}
Esempio n. 3
0
static int elektraResolveFilename (Key * parentKey, ElektraResolveTempfile tmpFile)
{
	int rc = 0;
	void * handle = elektraInvokeOpen ("resolver", 0, 0);
	if (!handle)
	{
		rc = -1;
		goto RESOLVE_FAILED;
	}
	ElektraResolved * resolved = NULL;
	typedef ElektraResolved * (*resolveFileFunc) (elektraNamespace, const char *, ElektraResolveTempfile, Key *);
	resolveFileFunc resolveFunc = *(resolveFileFunc *) elektraInvokeGetFunction (handle, "filename");

	if (!resolveFunc)
	{
		rc = -1;
		goto RESOLVE_FAILED;
	}

	typedef void (*freeHandleFunc) (ElektraResolved *);
	freeHandleFunc freeHandle = *(freeHandleFunc *) elektraInvokeGetFunction (handle, "freeHandle");

	if (!freeHandle)
	{
		rc = -1;
		goto RESOLVE_FAILED;
	}

	resolved = resolveFunc (keyGetNamespace (parentKey), keyString (parentKey), tmpFile, parentKey);

	if (!resolved)
	{
		rc = -1;
		goto RESOLVE_FAILED;
	}
	else
	{
		keySetString (parentKey, resolved->fullPath);
		freeHandle (resolved);
	}

RESOLVE_FAILED:
	elektraInvokeClose (handle, 0);
	return rc;
}
Esempio n. 4
0
/**
 * @brief decodes Base64 encoded data by utilizing libinvoke.
 * @param input holds the Base64 encoded data string
 * @param output will be set to an allocated buffer holding the decoded data or NULL if the allocation failed. Must be freed by the caller
	  on success.
 * @param outputLength will be set to the amount of decoded bytes.
 * @param errorKey will hold an error description if libinvoke fails.
 * @retval 1 on success
 * @retval -1 if the provided string has not been encoded with Base64
 * @retval -2 if the output buffer allocation failed
 * @retval -3 if libinvoke reported an error (errorKey is being set).
 */
int CRYPTO_PLUGIN_FUNCTION (base64Decode) (Key * errorKey, const char * input, kdb_octet_t ** output, size_t * outputLength)
{
	ElektraInvokeHandle * handle = elektraInvokeOpen ("base64", 0, errorKey);
	if (!handle)
	{
		return -3;
	}

	typedef int (*base64DecodeFunction) (const char * input, kdb_octet_t ** output, size_t * outputLength);
	base64DecodeFunction decodingFunction = *(base64DecodeFunction *) elektraInvokeGetFunction (handle, "base64Decode");

	if (!decodingFunction)
	{
		elektraInvokeClose (handle, 0);
		return -3;
	}

	int result = decodingFunction (input, output, outputLength);
	elektraInvokeClose (handle, 0);
	return result;
}
Esempio n. 5
0
/**
 * @brief Encodes arbitrary data using the Base64 schema by utilizing libinvoke.
 * @param errorKey will hold an error description if libinvoke fails.
 * @param input holds the data to be encoded
 * @param inputLength tells how many bytes the input buffer is holding.
 * @param output points to an allocated string holding the Base64 encoded input data or NULL if the string can not be allocated. Must be
 * freed by the caller.
 * @retval 1 on success
 * @retval -1 if libinvoke reported an error (errorKey is being set).
 */
int CRYPTO_PLUGIN_FUNCTION (base64Encode) (Key * errorKey, const kdb_octet_t * input, const size_t inputLength, char ** output)
{
	ElektraInvokeHandle * handle = elektraInvokeOpen ("base64", 0, errorKey);
	if (!handle)
	{
		return -1;
	}

	typedef char * (*base64EncodeFunction) (const kdb_octet_t * input, const size_t inputLength);
	base64EncodeFunction encodingFunction = *(base64EncodeFunction *) elektraInvokeGetFunction (handle, "base64Encode");

	if (!encodingFunction)
	{
		elektraInvokeClose (handle, 0);
		return -1;
	}

	*output = encodingFunction (input, inputLength);
	elektraInvokeClose (handle, 0);
	return 1;
}
Esempio n. 6
0
 * @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
 *
 */

#include "dini.h"

#include <kdbhelper.h>


int elektraDiniOpen (Plugin * handle, Key * errorKey ELEKTRA_UNUSED)
{
	Dini * dini = elektraMalloc (sizeof (Dini));

	dini->dumpConfig = ksDup (elektraPluginGetConfig (handle));
	dini->iniConfig = ksDup (elektraPluginGetConfig (handle));
	dini->dump = elektraInvokeOpen ("dump", dini->dumpConfig, 0);
	dini->ini = elektraInvokeOpen ("ini", dini->iniConfig, 0);
	dini->bin = elektraInvokeOpen ("binary", dini->iniConfig, 0);

	dini->dumpErrors = keyNew ("", KEY_END);

	elektraPluginSetData (handle, dini);

	return dini->ini ? ELEKTRA_PLUGIN_STATUS_SUCCESS : ELEKTRA_PLUGIN_STATUS_ERROR;
}

int elektraDiniClose (Plugin * handle, Key * errorKey ELEKTRA_UNUSED)
{
	Dini * dini = elektraPluginGetData (handle);

	elektraInvokeClose (dini->bin, 0);
Esempio n. 7
0
/** Initialize a plugin to be executed in its own process
 *
 * This will prepare all the required resources and then fork the current
 * process. After the initialization the child process will typically
 * call the command loop while the parent starts to send commands to it.
 * Also the resulting process information has to be stored for the plugin.
 * In order to allow users to handle custom plugin data this will not
 * automatically call elektraPluginSetData.
 *
 * Typically called in a plugin's open function like (assuming no custom plugin data):
 * @code
int elektraPluginOpen (Plugin * handle, Key * errorKey)
{
	ElektraPluginProcess * pp = elektraPluginGetData (handle);
	if (pp == NULL)
	{
		if ((pp = elektraPluginProcessInit (errorKey)) == NULL) return ELEKTRA_PLUGIN_STATUS_ERROR;
		elektraPluginSetData (handle, pp);
		if (!elektraPluginProcessIsParent (pp)) elektraPluginProcessStart (handle, pp);
	}
	if (elektraPluginProcessIsParent (pp)) return elektraPluginProcessOpen (pp, errorKey);

	// actual plugin functionality to be executed in a child process
	return ELEKTRA_PLUGIN_STATUS_SUCCESS;
}
 * @endcode
 *
 * @param handle the plugin's handle
 * @param errorKey a key where error messages will be set
 * @retval NULL if the initialization failed
 * @retval a pointer to the information
 * @ingroup processplugin
 **/
ElektraPluginProcess * elektraPluginProcessInit (Key * errorKey)
{
	// First time initialization
	ElektraPluginProcess * pp;
	pp = elektraMalloc (sizeof (ElektraPluginProcess));
	pp->counter = 0;
	pp->pluginData = NULL;
	pp->parentCommandPipeKey = NULL;
	pp->parentPayloadPipeKey = NULL;
	pp->childCommandPipeKey = NULL;
	pp->childPayloadPipeKey = NULL;

	pp->dump = elektraInvokeOpen ("dump", 0, errorKey);
	if (!pp->dump)
	{
		cleanupPluginData (pp, errorKey, 0);
		ELEKTRA_SET_ERROR (190, errorKey, "Failed to initialize the dump plugin");
		return NULL;
	}

	// As generally recommended, ignore SIGPIPE because we will notice that the
	// commandKeySet has been transferred incorrectly anyway to detect broken pipes
	signal (SIGPIPE, SIG_IGN);

	// Prepare the pipes
	if (!makePipe (pp, errorKey, "parentCommandPipe", pp->parentCommandPipe) ||
	    !makePipe (pp, errorKey, "parentPayloadPipe", pp->parentPayloadPipe) ||
	    !makePipe (pp, errorKey, "childCommandPipe", pp->childCommandPipe) ||
	    !makePipe (pp, errorKey, "childPayloadPipe", pp->childPayloadPipe))
		return NULL;

	pp->pid = fork ();

	if (pp->pid < 0)
	{
		cleanupPluginData (pp, errorKey, 1);
		ELEKTRA_SET_ERRORF (190, errorKey, "Failed to fork the plugin process, fork () returned %d", pp->pid);
		return NULL;
	}

	int pipeIdx = elektraPluginProcessIsParent (pp);
	close (pp->parentCommandPipe[!pipeIdx]);
	close (pp->parentPayloadPipe[!pipeIdx]);
	close (pp->childCommandPipe[pipeIdx]);
	close (pp->childPayloadPipe[pipeIdx]);

	ELEKTRA_LOG_DEBUG ("parentCommandPipe[%d] has file descriptor %d", pipeIdx, pp->parentCommandPipe[pipeIdx]);
	ELEKTRA_LOG_DEBUG ("parentPayloadPipe[%d] has file descriptor %d", pipeIdx, pp->parentPayloadPipe[pipeIdx]);
	ELEKTRA_LOG_DEBUG ("childCommandPipe[%d] has file descriptor %d", !pipeIdx, pp->childCommandPipe[!pipeIdx]);
	ELEKTRA_LOG_DEBUG ("childPayloadPipe[%d] has file descriptor %d", !pipeIdx, pp->childPayloadPipe[!pipeIdx]);

	// Prepare the keys for the pipes to use with dump
	pp->parentCommandPipeKey = makePipeKey ("parentCommandPipe", pp->parentCommandPipe[pipeIdx]);
	pp->parentPayloadPipeKey = makePipeKey ("parentPayloadPipe", pp->parentPayloadPipe[pipeIdx]);
	pp->childCommandPipeKey = makePipeKey ("childCommandPipe", pp->childCommandPipe[!pipeIdx]);
	pp->childPayloadPipeKey = makePipeKey ("childPayloadPipe", pp->childPayloadPipe[!pipeIdx]);

	ELEKTRA_LOG_DEBUG ("parentCommandPipeKey is %s on %d", keyString (pp->parentCommandPipeKey), pp->pid);
	ELEKTRA_LOG_DEBUG ("parentPayloadPipeKey is %s on %d", keyString (pp->parentPayloadPipeKey), pp->pid);
	ELEKTRA_LOG_DEBUG ("childCommandPipeKey is %s on %d", keyString (pp->childCommandPipeKey), pp->pid);
	ELEKTRA_LOG_DEBUG ("childPayloadPipeKey is %s on %d", keyString (pp->childPayloadPipeKey), pp->pid);

	ELEKTRA_LOG_DEBUG ("The pluginprocess is set with the pid %d", pp->pid);
	return pp;
}
Esempio n. 8
0
 * Note: To use this function with elektraInvoke2Args, call elektraInvokeOpen with a config containing
 * the key 'system/sendspec'. This postpones the check for an existent app until elektraSpecloadGet is called.
 *
 * @param handle    A specload plugin handle.
 * @param spec      The specification to send.
 * @param parentKey The parent key under which the target specload instance was mounted. Value unused.
 *
 * @retval #ELEKTRA_PLUGIN_STATUS_SUCCESS on success
 * @retval #ELEKTRA_PLUGIN_STATUS_ERROR on error
 */
int elektraSpecloadSendSpec (Plugin * handle ELEKTRA_UNUSED, KeySet * spec, Key * parentKey)
{
	Key * errorKey = keyNew (0, KEY_END);

	KeySet * quickDumpConf = ksNew (0, KS_END);
	ElektraInvokeHandle * quickDump = elektraInvokeOpen ("quickdump", quickDumpConf, errorKey);

	Key * quickDumpParent = keyNew (keyName (parentKey), KEY_VALUE, STDOUT_FILENAME, KEY_END);

	int result = elektraInvoke2Args (quickDump, "set", spec, quickDumpParent);

	elektraInvokeClose (quickDump, errorKey);
	keyDel (errorKey);
	keyDel (quickDumpParent);
	ksDel (quickDumpConf);

	return result == ELEKTRA_PLUGIN_STATUS_SUCCESS ? ELEKTRA_PLUGIN_STATUS_SUCCESS : ELEKTRA_PLUGIN_STATUS_ERROR;
}

int elektraSpecloadGet (Plugin * handle, KeySet * returned, Key * parentKey)
{