/** * 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); }
/** * @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; }
/** * @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; }
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; }
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; }
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); }