static KeySet * nextPackage (FILE * fp, Key * parentKey) { char * line = elektraMalloc (DPKG_LINE_MAX); KeySet * package = ksNew (500, KS_END); Key * lastKey = NULL; Key * baseKey = NULL; int notDone = 0; while (fgets (line, DPKG_LINE_MAX, fp) != NULL) { if (*line == '\n') break; if (*line == ' ') { if (strchr (line, '\n')) notDone = 0; else notDone = 1; appendToKey (lastKey, line); } else if (notDone) { if (strchr (line, '\n')) notDone = 0; appendToKey (lastKey, line); } else { if (!strchr (line, '\n')) notDone = 1; char * section = line; char * data = strchr (line, ':'); if (data) *data = '\0'; ++data; // skip : ++data; // skip whitespace strtok (data, "\n"); // remove newline if (!strcmp (section, "Package")) { baseKey = keyDup (parentKey); keyAddBaseName (baseKey, data); lastKey = baseKey; ksAppendKey (package, baseKey); } else { Key * key = keyDup (baseKey); keyAddBaseName (key, section); keySetString (key, data); lastKey = key; ksAppendKey (package, key); } } memset (line, 0, DPKG_LINE_MAX); } elektraFree (line); return package; }
/** * @brief Given filename, calculates dirname+tempfile * * @param p resolverHandle with filename set */ static void elektraResolveFinishByFilename (resolverHandle * p) { size_t filenameSize = strlen (p->filename); p->dirname = elektraMalloc (filenameSize); char * dup = strdup (p->filename); // dirname might change the buffer, so better work on a copy strcpy (p->dirname, dirname (dup)); elektraFree (dup); p->tempfile = elektraMalloc (filenameSize + POSTFIX_SIZE); elektraGenTempFilename (p->tempfile, p->filename); }
void test_resolve () { int pathLen = tempHomeLen + 1 + strlen (KDB_DB_USER) + 12 + 1; char * path = elektraMalloc (pathLen); exit_if_fail (path != 0, "elektraMalloc failed"); snprintf (path, pathLen, "%s/%s/elektra.ecf", tempHome, KDB_DB_USER); printf ("Resolve Filename\n"); KeySet * modules = ksNew (0, KS_END); elektraModulesInit (modules, 0); Key * parentKey = keyNew ("system", KEY_END); Plugin * plugin = elektraPluginOpen ("resolver", modules, set_pluginconf (), 0); exit_if_fail (plugin, "could not load resolver plugin"); KeySet * test_config = set_pluginconf (); KeySet * config = elektraPluginGetConfig (plugin); succeed_if (config != 0, "there should be a config"); compare_keyset (config, test_config); ksDel (test_config); succeed_if (plugin->kdbOpen != 0, "no open pointer"); succeed_if (plugin->kdbClose != 0, "no open pointer"); succeed_if (plugin->kdbGet != 0, "no open pointer"); succeed_if (plugin->kdbSet != 0, "no open pointer"); succeed_if (plugin->kdbError != 0, "no open pointer"); succeed_if (!strncmp (plugin->name, "resolver", strlen ("resolver")), "got wrong name"); resolverHandles * h = elektraPluginGetData (plugin); exit_if_fail (h != 0, "no plugin handle"); succeed_if_same_string (h->system.path, "elektra.ecf"); succeed_if_same_string (h->system.filename, KDB_DB_SYSTEM "/elektra.ecf"); succeed_if_same_string (h->user.path, "elektra.ecf"); succeed_if_same_string (h->user.filename, path); plugin->kdbClose (plugin, parentKey); // reinit with system path only plugin->kdbOpen (plugin, parentKey); h = elektraPluginGetData (plugin); exit_if_fail (h != 0, "no plugin handle"); succeed_if_same_string (h->system.path, "elektra.ecf"); succeed_if_same_string (h->system.filename, KDB_DB_SYSTEM "/elektra.ecf"); succeed_if (h->user.filename == NULL, "user was initialized, but is not needed"); plugin->kdbClose (plugin, parentKey); keyDel (parentKey); elektraPluginClose (plugin, 0); elektraModulesClose (modules, 0); ksDel (modules); elektraFree (path); }
int keySetOrderMeta (Key * key, int order) { char * buffer; int result; result = asprintf (&buffer, "%d", order); if (result < 0) return result; result = keySetMeta (key, "order", buffer); elektraFree (buffer); return result; }
static int foreachAugeasNode (augeas * handle, const char * treePath, ForeachAugNodeClb callback, void * callbackData) { char * matchPath; int result = 0; result = asprintf (&matchPath, "%s//*", treePath); if (result < 0) return -1; /* must be non NULL for aug_match to return matches */ char ** matches = (char **)1; int numMatches = aug_match (handle, matchPath, &matches); elektraFree (matchPath); if (numMatches < 0) return numMatches; int i; for (i = 0; i < numMatches; i++) { /* retrieve the value from augeas */ char * curPath = matches[i]; result = (*callback) (handle, curPath, callbackData); /* if handling the key failed, abort with an error as * the failed key could be a crucial one */ if (result < 0) break; elektraFree (curPath); } for (; i < numMatches; i++) { elektraFree (matches[i]); } elektraFree (matches); return result; }
static void test_commit (void) { printf ("test commit notification\n"); Key * parentKey = keyNew ("system/tests/foo", KEY_END); Key * toAdd = keyNew ("system/tests/foo/bar", KEY_END); KeySet * ks = ksNew (0, KS_END); KeySet * conf = ksNew (3, keyNew ("/endpoint", KEY_VALUE, TEST_ENDPOINT, KEY_END), keyNew ("/connectTimeout", KEY_VALUE, TESTCONFIG_CONNECT_TIMEOUT, KEY_END), keyNew ("/subscribeTimeout", KEY_VALUE, TESTCONFIG_SUBSCRIBE_TIMEOUT, KEY_END), KS_END); PLUGIN_OPEN ("zeromqsend"); // initial get to save current state plugin->kdbGet (plugin, ks, parentKey); // add key to keyset ksAppendKey (ks, toAdd); receiveTimeout = 0; receivedKeyName = NULL; receivedChangeType = NULL; pthread_t * thread = startNotificationReaderThread ("Commit"); plugin->kdbSet (plugin, ks, parentKey); pthread_join (*thread, NULL); succeed_if (receiveTimeout == 0, "receiving did time out"); succeed_if (!keyGetMeta (parentKey, "warnings"), "warning meta key was set"); succeed_if_same_string ("Commit", receivedChangeType); succeed_if_same_string (keyName (parentKey), receivedKeyName); ksDel (ks); keyDel (parentKey); PLUGIN_CLOSE (); elektraFree (receivedKeyName); elektraFree (receivedChangeType); elektraFree (thread); }
/** * Key Object Cleaner. * * Will reset all internal data. * * After this call you will receive a fresh * key. * * The reference counter will stay unmodified. * * @note that you might also clear() all aliases * with this operation. * * @code int f (Key *k) { keyClear (k); // you have a fresh key k here keySetString (k, "value"); // the caller will get an empty key k with an value } * @endcode * * @retval returns 0 on success * @retval -1 on null pointer * * @param key the key object to work with * @ingroup key */ int keyClear (Key * key) { if (!key) { return -1; } size_t ref = 0; ref = key->ksReference; if (key->key) elektraFree (key->key); if (key->data.v) elektraFree (key->data.v); if (key->meta) ksDel (key->meta); keyInit (key); /* Set reference properties */ key->ksReference = ref; return 0; }
/** * Outputs the help message to stdout * * @param usage If this is not NULL, it will be used instead of the default usage line. * @param prefix If this is not NULL, it will be inserted between the usage line and the options list. */ void printHelpMessage (const char * usage, const char * prefix) { if (helpKey == NULL) { return; } char * help = elektraGetOptsHelpMessage (helpKey, usage, prefix); printf ("%s", help); elektraFree (help); keyDel (helpKey); helpKey = NULL; }
static int foreachAugeasNode(augeas *handle, const char *treePath, ForeachAugNodeClb callback, void *callbackData) { char *matchPath; asprintf (&matchPath, "%s/*", treePath); /* must be non NULL for aug_match to return matches */ char **matches = (char **) 1; int numMatches = aug_match (handle, matchPath, &matches); elektraFree (matchPath); if (numMatches < 0) return numMatches; int i; int result = 0; for (i = 0; i < numMatches; i++) { /* retrieve the value from augeas */ char *curPath = matches[i]; result = (*callback) (handle, curPath, callbackData); /* handle the subtree */ result = foreachAugeasNode (handle, curPath, callback, callbackData); if (result < 0) break; elektraFree (curPath); } for (; i < numMatches; i++) { elektraFree (matches[i]); } elektraFree (matches); return result; }
static int isValidSuffix (char * suffix, const Key * suffixList) { if (!suffixList) return 0; char * searchString = elektraMalloc (strlen (suffix) + 3); snprintf (searchString, strlen (suffix) + 3, "'%s'", suffix); int ret = 0; if (strstr (keyString (suffixList), searchString)) { ret = 1; } elektraFree (searchString); return ret; }
/** * @internal * Create a new key with a different root or common name. * * Does not modify `key`. The new key needs to be freed after usage. * * Preconditions: The key name starts with `source`. * * Example: * ``` * Key * source = keyNew("user/plugins/foo/placements/get", KEY_END); * Key * dest = renameKey ("user/plugins/foo", "user/plugins/bar", source); * succeed_if_same_string (keyName(dest), "user/plugins/bar/placements/get"); * ``` * * * @param source Part of the key name to replace * @param dest Replaces `source` * @param key key * @return key with new name */ static Key * renameKey (const char * source, const char * dest, Key * key) { const char * name = keyName (key); char * baseKeyNames = strndup (name + strlen (source), strlen (name)); Key * moved = keyDup (key); keySetName (moved, dest); keyAddName (moved, baseKeyNames); elektraFree (baseKeyNames); return moved; }
/** * Adds @p baseName (that will be escaped) to the current key name. * * A new baseName will be added, no other part of the key name will be * affected. * * Assumes that @p key is a directory and will append @p baseName to it. * The function adds the path separator for concatenating. * * So if @p key has name @c "system/dir1/dir2" and this method is called with * @p baseName @c "mykey", the resulting key will have the name * @c "system/dir1/dir2/mykey". * * When @p baseName is 0 nothing will happen and the size of the name is returned. * * The escaping rules apply as in @link keyname above @endlink. * * A simple example is: * @snippet basename.c add base basic * * E.g. if you add . it will be escaped: * @snippet testabi_key.c base1 add * * @see keySetBaseName() to set a base name * @see keySetName() to set a new name. * * @param key the key object to work with * @param baseName the string to append to the name * @return the size in bytes of the new key name including the ending NULL * @retval -1 if the key had no name * @retval -1 on NULL pointers * @retval -1 if key was inserted to a keyset before * @ingroup keyname * */ ssize_t keyAddBaseName (Key * key, const char * baseName) { if (!key) return -1; if (!baseName) return key->keySize; if (test_bit (key->flags, KEY_FLAG_RO_NAME)) return -1; if (!key->key) return -1; char * escaped = elektraMalloc (strlen (baseName) * 2 + 2); elektraEscapeKeyNamePart (baseName, escaped); size_t len = strlen (escaped); if (!strcmp (key->key, "/")) { key->keySize += len; } else { key->keySize += len + 1; } elektraRealloc ((void **)&key->key, key->keySize * 2); if (!key->key) { elektraFree (escaped); return -1; } if (strcmp (key->key, "/")) { key->key[key->keySize - len - 2] = KDB_PATH_SEPARATOR; } memcpy (key->key + key->keySize - len - 1, escaped, len); elektraFree (escaped); elektraFinalizeName (key); return key->keySize; }
static void elektraResolveFinishByDirname (ElektraResolved * handle, ElektraResolveTempfile tmpDir) { size_t filenameSize = elektraStrLen (handle->relPath) + elektraStrLen (handle->dirname); char * filename = elektraMalloc (filenameSize); strcpy (filename, handle->dirname); if (handle->relPath[0] != '/') { strcat (filename, "/"); } strcat (filename, handle->relPath); elektraFree (handle->dirname); handle->fullPath = filename; elektraResolveFinishByFilename (handle, tmpDir); }
/** * Closes the session with the Key database. * * @pre The handle must be a valid handle as returned from kdbOpen() * * @pre errorKey must be a valid key, e.g. created with keyNew() * * This is the counterpart of kdbOpen(). * * You must call this method when you finished your affairs with the key * database. You can manipulate Key and KeySet objects also after * kdbClose(), but you must not use any kdb*() call afterwards. * * The @p handle parameter will be finalized and all resources associated to it * will be freed. After a kdbClose(), the @p handle cannot be used anymore. * * @param handle contains internal information of * @link kdbOpen() opened @endlink key database * @param errorKey the key which holds error/warning information * @retval 0 on success * @retval -1 on NULL pointer * @ingroup kdb */ int kdbClose (KDB * handle, Key * errorKey) { if (!handle) { return -1; } Key * initialParent = keyDup (errorKey); int errnosave = errno; splitDel (handle->split); trieClose (handle->trie, errorKey); backendClose (handle->defaultBackend, errorKey); handle->defaultBackend = 0; // not set in fallback mode, so lets check: if (handle->initBackend) { backendClose (handle->initBackend, errorKey); handle->initBackend = 0; } for (int i = 0; i < NR_GLOBAL_POSITIONS; ++i) { for (int j = 0; j < NR_GLOBAL_SUBPOSITIONS; ++j) { elektraPluginClose (handle->globalPlugins[i][j], errorKey); } } if (handle->modules) { elektraModulesClose (handle->modules, errorKey); ksDel (handle->modules); } else { ELEKTRA_ADD_WARNING (47, errorKey, "modules were not open"); } elektraFree (handle); keySetName (errorKey, keyName (initialParent)); keySetString (errorKey, keyString (initialParent)); keyDel (initialParent); errno = errnosave; return 0; }
static char * elektraResolvePasswd (Key * warningsKey) { ssize_t bufSize = sysconf (_SC_GETPW_R_SIZE_MAX); if (bufSize == -1) bufSize = 16384; // man 3 getpwuid char * buf = elektraMalloc (bufSize); if (!buf) return NULL; struct passwd pwd; struct passwd * result; int s = getpwuid_r (getuid (), &pwd, buf, bufSize, &result); if (result == NULL) { elektraFree (buf); if (s != 0) { ELEKTRA_ADD_WARNING (90, warningsKey, strerror (s)); } return NULL; } char * resolved = elektraStrDup (pwd.pw_dir); elektraFree (buf); return resolved; }
void test_decode (void) { printf ("test decode\n"); CCodeData * d = get_data (); char buf[1000]; d->buf = buf; Key * test = keyNew ("user/test", KEY_SIZE, sizeof (encoded_string) - 1, KEY_VALUE, encoded_string, KEY_END); elektraCcodeDecode (test, d); succeed_if (!memcmp (keyValue (test), decoded_string, sizeof (decoded_string) - 1), "string not correctly encoded"); elektraFree (d); keyDel (test); }
/** * A destructor for Key objects. * * Every key created by keyNew() must be * deleted with keyDel(). * * It is save to delete keys which are * in a keyset, the number of references * will be returned then. * * It is save to delete a nullpointer, * -1 will be returned then. * * It is also save to delete a multiple * referenced key, nothing will happen * then and the reference counter will * be returned. * * @param key the key object to delete * @see keyNew(), keyIncRef(), keyGetRef() * @return the value of the reference counter * if the key is within keyset(s) * @retval 0 when the key was freed * @retval -1 on null pointers * @ingroup key * */ int keyDel (Key * key) { int rc; if (!key) return -1; if (key->ksReference > 0) { return key->ksReference; } rc = keyClear (key); elektraFree (key); return rc; }
static int handleErrors (Key * parentKey, KeySet * ks, Key * key, Key * specKey, ConflictHandling * ch, Direction dir) { cursor_t cursor = ksGetCursor (ks); int ret = 0; ConflictHandling * localCh = elektraMalloc (sizeof (ConflictHandling)); memcpy (localCh, ch, sizeof (ConflictHandling)); parseLocalConfig (specKey, localCh, dir); Key * parentLookup = keyDup (key); keySetBaseName (parentLookup, 0); Key * parent = ksLookup (ks, parentLookup, KDB_O_NONE); keyDel (parentLookup); keyRewindMeta (parent); Conflict conflict; Key * meta; while (keyNextMeta (parent) != NULL) { meta = (Key *) keyCurrentMeta (parent); conflict = getConflict (meta); if (conflict != NAC) { ret |= handleError (parentKey, parent, specKey, meta, conflict, localCh); keySetMeta (parent, keyName (meta), 0); } else if (!strncmp (keyName (meta), "conflict/#", 10) || !strncmp (keyName (meta), "conflict/invalid/hasmember/#", 28)) { keySetMeta (parent, keyName (meta), 0); } } keyRewindMeta (key); while (keyNextMeta (key) != NULL) { meta = (Key *) keyCurrentMeta (key); conflict = getConflict (meta); if (conflict != NAC) { ret |= handleError (parentKey, key, specKey, meta, conflict, localCh); keySetMeta (key, keyName (meta), 0); } else if (!strncmp (keyName (meta), "conflict/#", 10) || !strncmp (keyName (meta), "conflict/invalid/hasmember/#", 28)) { keySetMeta (key, keyName (meta), 0); } } elektraFree (localCh); ksSetCursor (ks, cursor); return ret; }
/** * @brief derive the cryptographic key and IV for a given (Elektra) Key k * @param config KeySet holding the plugin/backend configuration * @param errorKey holds an error description in case of failure * @param masterKey holds the decrypted master password from the plugin configuration * @param k the (Elektra)-Key to be encrypted * @param cKey (Elektra)-Key holding the cryptographic material * @param cIv (Elektra)-Key holding the initialization vector * @retval -1 on failure. errorKey holds the error description. * @retval 1 on success */ static int getKeyIvForEncryption (KeySet * config, Key * errorKey, Key * masterKey, Key * k, Key * cKey, Key * cIv) { kdb_octet_t salt[ELEKTRA_CRYPTO_DEFAULT_SALT_LEN] = { 0 }; kdb_octet_t keyBuffer[KEY_BUFFER_SIZE] = { 0 }; char * saltHexString = NULL; ELEKTRA_ASSERT (masterKey != NULL, "Parameter `masterKey` must not be NULL"); // generate the salt pthread_mutex_lock (&mutex_ssl); if (!RAND_bytes (salt, ELEKTRA_CRYPTO_DEFAULT_SALT_LEN - 1)) { ELEKTRA_SET_ERRORF (ELEKTRA_ERROR_CRYPTO_INTERNAL_ERROR, errorKey, "failed to generate random salt with error code %lu", ERR_get_error ()); pthread_mutex_unlock (&mutex_ssl); return -1; } pthread_mutex_unlock (&mutex_ssl); saltHexString = ELEKTRA_PLUGIN_FUNCTION (ELEKTRA_PLUGIN_NAME_C, base64Encode) (salt, sizeof (salt)); if (!saltHexString) { ELEKTRA_SET_ERROR (87, errorKey, "Memory allocation failed"); return -1; } keySetMeta (k, ELEKTRA_CRYPTO_META_SALT, saltHexString); elektraFree (saltHexString); // read iteration count const kdb_unsigned_long_t iterations = CRYPTO_PLUGIN_FUNCTION (getIterationCount) (errorKey, config); // generate/derive the cryptographic key and the IV pthread_mutex_lock (&mutex_ssl); if (!PKCS5_PBKDF2_HMAC_SHA1 (keyValue (masterKey), keyGetValueSize (masterKey), salt, sizeof (salt), iterations, KEY_BUFFER_SIZE, keyBuffer)) { ELEKTRA_SET_ERRORF (ELEKTRA_ERROR_CRYPTO_INTERNAL_ERROR, errorKey, "Failed to create a cryptographic key for encryption. Libcrypto returned error code: %lu", ERR_get_error ()); pthread_mutex_unlock (&mutex_ssl); return -1; } pthread_mutex_unlock (&mutex_ssl); keySetBinary (cKey, keyBuffer, ELEKTRA_CRYPTO_SSL_KEYSIZE); keySetBinary (cIv, keyBuffer + ELEKTRA_CRYPTO_SSL_KEYSIZE, ELEKTRA_CRYPTO_SSL_BLOCKSIZE); return 1; }
void test_decodeescape (void) { printf ("test decode escape\n"); CCodeData * d = get_data (); d->encode['\\'] = '\\'; d->decode['\\'] = '\\'; char buf[1000]; d->buf = buf; Key * test = keyNew ("user/test", KEY_SIZE, 2, KEY_VALUE, "\\\\", KEY_END); elektraCcodeDecode (test, d); succeed_if (!memcmp (keyValue (test), "\\", 2), "string not correctly encoded"); elektraFree (d); keyDel (test); }
// TODO: this is very similar to elektraKeyAppendMetaLine in keytometa static int elektraKeyAppendLine (Key *target, const char *line) { if (!target) return 0; if (!line) return 0; char *buffer = elektraMalloc (keyGetValueSize(target) + strlen (line) + 1); if (!buffer) return 0; keyGetString(target, buffer, keyGetValueSize(target)); strcat (buffer, "\n"); strncat (buffer, line, strlen (line)); keySetString(target, buffer); elektraFree (buffer); return keyGetValueSize(target); }
void check_reversibility (const char * msg) { CCodeData * d = get_data (); char buf[1000]; d->buf = buf; Key * decode = keyNew ("user/test", KEY_VALUE, msg, KEY_END); Key * encode = keyDup (decode); elektraCcodeEncode (encode, d); elektraCcodeDecode (encode, d); compare_key (encode, decode); elektraFree (d); keyDel (decode); keyDel (encode); }
static int fcryptGpgCallAndCleanup (Key * parentKey, KeySet * pluginConfig, char ** argv, int argc, int tmpFileFd, char * tmpFile) { int parentKeyFd = -1; int result = ELEKTRA_PLUGIN_FUNCTION (gpgCall) (pluginConfig, parentKey, NULL, argv, argc); if (result == 1) { parentKeyFd = open (keyString (parentKey), O_WRONLY); // gpg call returned success, overwrite the original file with the gpg payload data if (rename (tmpFile, keyString (parentKey)) != 0) { ELEKTRA_SET_ERRORF (31, parentKey, "Renaming file %s to %s failed.", tmpFile, keyString (parentKey)); result = -1; } } if (result == 1) { if (parentKeyFd >= 0) { shredTemporaryFile (parentKeyFd, parentKey); } } else { // if anything went wrong above the temporary file is shredded and removed shredTemporaryFile (tmpFileFd, parentKey); if (unlink (tmpFile)) { ELEKTRA_ADD_WARNINGF (ELEKTRA_WARNING_FCRYPT_UNLINK, parentKey, "Affected file: %s, error description: %s", tmpFile, strerror (errno)); } } if (parentKeyFd >= 0 && close (parentKeyFd)) { ELEKTRA_ADD_WARNINGF (ELEKTRA_WARNING_FCRYPT_CLOSE, parentKey, "%s", strerror (errno)); } if (close (tmpFileFd)) { ELEKTRA_ADD_WARNINGF (ELEKTRA_WARNING_FCRYPT_CLOSE, parentKey, "%s", strerror (errno)); } elektraFree (tmpFile); return result; }
void test_decode (void) { printf ("test decode\n"); CHexData * hd = calloc (1, sizeof (CHexData)); hd->escape = '\\'; char buf[1000]; hd->buf = buf; Key * test = keyNew ("user/test", KEY_SIZE, sizeof (encoded_string) - 1, KEY_VALUE, encoded_string, KEY_END); elektraHexcodeDecode (test, hd); succeed_if (!strcmp (keyString (test), decoded_string), "string not correctly encoded"); elektraFree (hd); keyDel (test); }
static Key *createUnescapedKey(Key *key, const char *name) { char *localString = strdup(name); char *newBaseName = strtok(localString, "/"); if (newBaseName != NULL) keyAddBaseName(key, newBaseName); while (newBaseName != NULL) { newBaseName = strtok(NULL, "/"); if (newBaseName != NULL) { keyAddBaseName(key, newBaseName); } } elektraFree (localString); return key; }
static inline char * readString (FILE * file, Key * errorKey) { kdb_unsigned_long_long_t size; if (!readUInt64 (file, &size, errorKey)) { ELEKTRA_SET_ERROR (ELEKTRA_ERROR_READ_FAILED, errorKey, feof (file) ? "premature end of file" : "unknown error"); return NULL; } char * string = elektraMalloc (size + 1); if (fread (string, sizeof (char), size, file) < size) { ELEKTRA_SET_ERROR (ELEKTRA_ERROR_READ_FAILED, errorKey, feof (file) ? "premature end of file" : "unknown error"); elektraFree (string); return NULL; } string[size] = '\0'; return string; }
static void test_keySetString (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]; KeySet * ks = metaTestKeySet (); const char * name = "user/tests/storage/specialkey"; const char * value = "special value"; size_t realValueSize = elektraStrLen (value); Key * key = keyNew (name, KEY_VALUE, value, KEY_END); ksAppendKey (ks, key); succeed_if (plugin->kdbSet (plugin, ks, parentKey) == 1, "kdbSet was not successful"); succeed_if (plugin->kdbGet (plugin, ks, parentKey) == 1, "kdbGet was not successful"); Key * found = ksLookupByName (ks, name, KDB_O_POP); succeed_if (found, "did not find key"); // now set a new key string to the Key _after_ kdbGet const char * newValue = "some new special value"; size_t newValueSize = elektraStrLen (newValue); succeed_if (keySetString (found, newValue) == (ssize_t) newValueSize, "Key string could not be set"); ksAppendKey (ks, found); succeed_if (plugin->kdbSet (plugin, ks, parentKey) == 1, "kdbSet was not successful"); succeed_if (plugin->kdbGet (plugin, ks, parentKey) == 1, "kdbGet was not successful"); found = ksLookupByName (ks, name, 0); succeed_if (found, "did not find key"); ssize_t apiValueSize = keyGetValueSize (found); char * apiValue = elektraMalloc (apiValueSize); succeed_if (keyGetString (found, apiValue, apiValueSize) == (ssize_t) newValueSize, "Key string has wrong size"); succeed_if (elektraStrNCmp (value, apiValue, realValueSize) != 0, "Key string value is wrong"); succeed_if (elektraStrNCmp (newValue, apiValue, newValueSize) == 0, "Key string value is wrong"); elektraFree (apiValue); keyDel (parentKey); ksDel (ks); closeStoragePlugin (storagePlugin); }
int elektraAugeasOpen(Plugin *handle, Key *parentKey) { augeas *augeasHandle; augeasHandle = aug_init (NULL, NULL, AUG_NO_MODL_AUTOLOAD | AUG_NO_ERR_CLOSE); if (aug_error (augeasHandle) != AUG_NOERROR) { char *errormessage; asprintf (&errormessage, "Unable to initialize augeas: %s", aug_error_message (augeasHandle)); ELEKTRA_SET_ERROR(85, parentKey, errormessage); elektraFree (errormessage); return -1; } elektraPluginSetData (handle, augeasHandle); return 0; }
static int gpg_available (KeySet * conf) { int available = 0; char * gpgPath = NULL; Key * parentKey = keyNew ("system", KEY_END); int gpg_search_result = ELEKTRA_PLUGIN_FUNCTION (gpgGetBinary) (&gpgPath, conf, parentKey); if (gpg_search_result == 1) { available = 1; } if (gpgPath) { elektraFree (gpgPath); } keyDel (parentKey); ksDel (conf); return available; }
/** * Lookups a backend inside the trie. * * @return the backend if found * @return 0 otherwise * @param trie the trie object to work with * @param key the name of this key will be looked up * @ingroup trie */ Backend* elektraTrieLookup(Trie *trie, const Key *key) { char *where=0; Backend *ret=0; size_t len=0; if (!key) return 0; if (!trie) return 0; len = keyGetNameSize(key) + 1; if (len == 1) return 0; // would crash otherwise where = elektraMalloc(len); strncpy(where, keyName(key), len); where[len-2] = '/'; ret = elektraTriePrefixLookup(trie,where); elektraFree(where); return ret; }