/**
 * 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);
}
예제 #2
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;
}
예제 #3
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;
}
예제 #4
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;
}
예제 #5
0
int elektraSpecloadClose (Plugin * handle, Key * errorKey)
{
	Specload * specload = elektraPluginGetData (handle);

	if (specload != NULL)
	{
		elektraInvokeClose (specload->quickDump, errorKey);

		ksDel (specload->quickDumpConfig);
		elektraFree (specload->app);
		freeArgv (specload->argv);

		elektraFree (specload);
		elektraPluginSetData (handle, NULL);
	}

	return ELEKTRA_PLUGIN_STATUS_SUCCESS;
}
예제 #6
0
static void cleanupPluginData (ElektraPluginProcess * pp, Key * errorKey, int cleanAllPipes)
{
	if (pp->dump) elektraInvokeClose (pp->dump, errorKey);

	if (pp->parentCommandPipeKey) keyDel (pp->parentCommandPipeKey);
	if (pp->parentPayloadPipeKey) keyDel (pp->parentPayloadPipeKey);
	if (pp->childCommandPipeKey) keyDel (pp->childCommandPipeKey);
	if (pp->childPayloadPipeKey) keyDel (pp->childPayloadPipeKey);

	// twisted way to clean either both ends if something failed upon or before forking
	// and the used ends otherwise
	for (int pipeIdx = !elektraPluginProcessIsParent (pp); pipeIdx <= cleanAllPipes; ++pipeIdx)
	{
		if (pp->parentCommandPipe[!pipeIdx]) close (pp->parentCommandPipe[!pipeIdx]);
		if (pp->parentPayloadPipe[!pipeIdx]) close (pp->parentPayloadPipe[!pipeIdx]);
		if (pp->childCommandPipe[pipeIdx]) close (pp->childCommandPipe[pipeIdx]);
		if (pp->childPayloadPipe[pipeIdx]) close (pp->childPayloadPipe[pipeIdx]);
	}

	elektraFree (pp);
}