/** * @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"); } }
void test_readfstab(const char * file) { Key * parentKey = keyNew ("user/tests/fstab", KEY_VALUE, srcdir_file(file), KEY_END); KeySet *conf = 0; PLUGIN_OPEN("fstab"); KeySet *ks=ksNew(0, KS_END); printf ("Reading fstab using file: %s\n", file); succeed_if (plugin->kdbGet(plugin, ks, parentKey) >= 1, "call to kdbGet was not successful"); // output_keyset(ks); Key *key = ksLookupByName(ks, "user/tests/fstab/\\//device",0); exit_if_fail (key, "rootfs device not found"); succeed_if (strcmp( "/dev/sda1", keyValue(key)) == 0, "device not correct"); key = ksLookupByName(ks, "user/tests/fstab/\\/media\\/ext4/device",0); exit_if_fail (key, "media device not found"); succeed_if (strcmp( "/dev/sdg1", keyValue(key)) == 0, "device not correct"); exit_if_fail (key = ksLookupByName(ks, "user/tests/fstab/\\/media\\/ext4/dumpfreq",0), "rootfs device not found"); succeed_if (strcmp( "0", keyValue(key)) == 0, "dumpfreq not correct"); ksDel(ks); keyDel(parentKey); PLUGIN_CLOSE(); }
int itemNextStep(LWEnvelopeID *env, LWEnvKeyframeID *k, int *step, LWDVector val) { int i, curstep, newstep; double t; i = MINDEX(step); curstep = step[i]; newstep = curstep; t = curstep; t /= sceneInfo->framesPerSecond; if(step[0]==curstep && k[0]) { val[0] = keyValue(env,k[0]); if(k[0] = envInfo->nextKey(env[0],k[0])) { step[0] = keyStep(env,k[0]); newstep = step[0]; } } else { val[0] = envInfo->evaluate(env[0], t); } if(step[1]==curstep && k[1]) { val[1] = keyValue(env,k[1]); if(k[1] = envInfo->nextKey(env[1],k[1])) { step[1] = keyStep(env,k[1]); newstep = newstep>curstep ? MIN(newstep,step[1]):step[1]; } } else { val[1] = envInfo->evaluate(env[1], t); } if(step[2]==curstep && k[2]) { val[2] = keyValue(env,k[2]); if(k[2] = envInfo->nextKey(env[2],k[2])) { step[2] = keyStep(env,k[2]); newstep = newstep>curstep ? MIN(newstep,step[2]):step[2]; } } else { val[2] = envInfo->evaluate(env[2], t); } if(!k[0]) step[0] = newstep; if(!k[1]) step[1] = newstep; if(!k[2]) step[2] = newstep; return curstep; }
void test_zeroMatchFlags (void) { Key * parentKey = keyNew ("user/tests/glob", KEY_END); KeySet * conf = ksNew (20, keyNew ("user/glob/#1", KEY_VALUE, "*test1", KEY_META, "testmetakey1", "testvalue1", KEY_END), /* disable default pathname globbing behaviour */ keyNew ("user/glob/#1/flags", KEY_VALUE, "", KEY_END), KS_END); PLUGIN_OPEN ("glob"); KeySet * ks = createKeys (); succeed_if (plugin->kdbSet (plugin, ks, parentKey) >= 1, "call to kdbSet was not successful"); succeed_if (output_error (parentKey), "error in kdbSet"); succeed_if (output_warnings (parentKey), "warnings in kdbSet"); Key * key = ksLookupByName (ks, "user/tests/glob/test1", 0); exit_if_fail (key, "key user/tests/glob/test1 not found"); const Key * metaKey1 = keyGetMeta (key, "testmetakey1"); exit_if_fail (metaKey1, "testmetakey1 not found"); succeed_if (strcmp ("testvalue1", keyValue (metaKey1)) == 0, "value of metakey testmetakey1 not correct"); key = ksLookupByName (ks, "user/tests/glob/test3", 0); exit_if_fail (key, "user/tests/glob/test3 not found"); succeed_if (!keyGetMeta (key, "testmetakey1"), "testmetakey1 copied to wrong key"); key = ksLookupByName (ks, "user/tests/glob/test2/subtest1", 0); exit_if_fail (key, "user/tests/glob/test2/subtest1 not found"); const Key * metaKey2 = keyGetMeta (key, "testmetakey1"); exit_if_fail (metaKey2, "testmetakey1 not found"); succeed_if (strcmp ("testvalue1", keyValue (metaKey2)) == 0, "value of metakey testmetakey1 not correct"); ksDel (ks); keyDel (parentKey); PLUGIN_CLOSE (); }
void testKeys (KeySet * ks) { Key * key = ksLookupByName (ks, "user/tests/glob/test1", 0); exit_if_fail (key, "key user/tests/glob/test1 not found"); const Key * metaKey = keyGetMeta (key, "testmetakey1"); exit_if_fail (metaKey, "testmetakey1 not found"); succeed_if (strcmp ("testvalue1", keyValue (metaKey)) == 0, "value of metakey testmetakey1 not correct"); metaKey = keyGetMeta (key, "testmetakey2"); exit_if_fail (metaKey, "testmetakey2 not found"); succeed_if (strcmp ("testvalue2", keyValue (metaKey)) == 0, "value of metakey testmetakey2 not correct"); key = ksLookupByName (ks, "user/tests/glob/test2/subtest1", 0); exit_if_fail (key, "key user/test1/subtest1 not found"); succeed_if (!keyGetMeta (key, "testmetakey1"), "testmetakey1 copied to wrong key"); succeed_if (!keyGetMeta (key, "testmetakey2"), "testmetakey2 copied to wrong key"); key = ksLookupByName (ks, "user/tests/glob/test3", 0); exit_if_fail (key, "key user/tests/glob/test3 not found"); metaKey = keyGetMeta (key, "testmetakey1"); exit_if_fail (metaKey, "testmetakey1 not found"); succeed_if (strcmp ("testvalue1", keyValue (metaKey)) == 0, "value of metakey testmetakey1 not correct"); metaKey = keyGetMeta (key, "testmetakey2"); exit_if_fail (metaKey, "testmetakey2 not found"); succeed_if (strcmp ("testvalue2", keyValue (metaKey)) == 0, "value of metakey testmetakey2 not correct"); }
/** * Compare 2 keys. * * The returned flags bit array has 1s (differ) or 0s (equal) for each key * meta info compared, that can be logically ORed using @c #keyswitch_t flags. * @link keyswitch_t::KEY_NAME KEY_NAME @endlink, * @link keyswitch_t::KEY_VALUE KEY_VALUE @endlink, * @link keyswitch_t::KEY_OWNER KEY_OWNER @endlink, * @link keyswitch_t::KEY_COMMENT KEY_COMMENT @endlink, * @link keyswitch_t::KEY_UID KEY_UID @endlink, * @link keyswitch_t::KEY_GID KEY_GID @endlink, * @link keyswitch_t::KEY_MODE KEY_MODE @endlink and * * @par A very simple example would be * @code Key *key1, *key; uint32_t changes; // omited key1 and key2 initialization and manipulation changes=keyCompare(key1,key2); if (changes == 0) printf("key1 and key2 are identicall\n"); if (changes & KEY_VALUE) printf("key1 and key2 have different values\n"); if (changes & KEY_UID) printf("key1 and key2 have different UID\n"); * * @endcode * * * @par Example of very powerful specific Key lookup in a KeySet: * @code KDB *handle = kdbOpen(); KeySet *ks=ksNew(0); Key *base = keyNew ("user/sw/MyApp/something", KEY_END); Key *current; uint32_t match; uint32_t interests; kdbGetByName(handle, ks, "user/sw/MyApp", 0); // we are interested only in key type and access permissions interests=(KEY_TYPE | KEY_MODE); ksRewind(ks); // put cursor in the beginning while ((curren=ksNext(ks))) { match=keyCompare(current,base); if ((~match & interests) == interests) printf("Key %s has same type and permissions of base key",keyName(current)); // continue walking in the KeySet.... } // now we want same name and/or value interests=(KEY_NAME | KEY_VALUE); // we don't really need ksRewind(), since previous loop achieved end of KeySet ksRewind(ks); while ((current=ksNext(ks))) { match=keyCompare(current,base); if ((~match & interests) == interests) { printf("Key %s has same name, value, and sync status of base key",keyName(current)); } // continue walking in the KeySet.... } keyDel(base); ksDel(ks); kdbClose (handle); * @endcode * * @return a bit array pointing the differences * @param key1 first key * @param key2 second key * @see #keyswitch_t * @ingroup keytest */ keyswitch_t keyCompare(const Key *key1, const Key *key2) { if (!key1 && !key2) return 0; if (!key1 || !key2) return KEY_NULL; keyswitch_t ret=0; ssize_t nsize1 = keyGetNameSize(key1); ssize_t nsize2 = keyGetNameSize(key2); const char *name1 = keyName(key1); const char *name2 = keyName(key2); const char *comment1 = keyComment(key1); const char *comment2 = keyComment(key2); const char *owner1 = keyOwner(key1); const char *owner2 = keyOwner(key2); const void *value1 = keyValue(key1); const void *value2 = keyValue(key2); ssize_t size1 = keyGetValueSize(key1); ssize_t size2 = keyGetValueSize(key2); if (keyGetUID(key1) != keyGetUID(key2)) ret|=KEY_UID; if (keyGetGID(key1) != keyGetGID(key2)) ret|=KEY_GID; if (keyGetMode(key1)!= keyGetMode(key2)) ret|=KEY_MODE; if (nsize1 != nsize2) ret|=KEY_NAME; if (strcmp(name1, name2)) ret|=KEY_NAME; if (strcmp(comment1, comment2)) ret|=KEY_COMMENT; if (strcmp(owner1, owner2)) ret|=KEY_OWNER; if (size1 != size2) ret|=KEY_VALUE; if (memcmp(value1, value2, size1)) ret|=KEY_VALUE; return ret; }
void test_readline(){ char * filename = srcdir_file("line/linetest"); Key * parentKey = keyNew ("user/tests/line", KEY_VALUE, filename, KEY_END); KeySet *conf = 0; PLUGIN_OPEN("line"); printf("%s\n", filename); KeySet *ks=ksNew(0, KS_END); succeed_if (plugin->kdbGet(plugin, ks, parentKey) >= 1, "call to kdbGet was not successful"); Key *key = ksLookupByName(ks, "user/tests/line/#0", 0); exit_if_fail (key, "line1 key not found"); succeed_if (strcmp("test1", keyValue(key)) == 0, "line ´ does not match"); key = ksLookupByName(ks, "user/tests/line/#_10", 0); exit_if_fail (key, "line11 key not found"); succeed_if (strcmp("", keyValue(key)) == 0, "line 10 should be blank"); key = ksLookupByName(ks, "user/tests/line/#_13", 0); exit_if_fail (key, "line14 key not found"); succeed_if (strcmp("printf(\"hello world\\n\");", keyValue(key)) == 0, "line 13 not correct"); ksDel (ks); keyDel(parentKey); PLUGIN_CLOSE(); }
int main() { char in1[][30] = {"SET a 1", "SET b 2", "GET a", "COMMIT", "SET b 3"}; char in2[][30] = {"GET b", "SET b 4"}; char in3[][30] = {"GET b"}; keyValue(in1, 5); keyValue(in2, 2); keyValue(in3, 1); }
int main (int argc,char *argv[]) { char d1[][30]={"SET a 1","SET b 2","GET a","COMMIT","SET b 3"}; char d2[][30]={"GET b","SET b 4"}; char d3[][30]={"GET b"}; keyValue(d1,5); keyValue(d2,2); keyValue(d3,1); return 0; }
void test_keyset() { KeySet *ks; Key *cur; int counter; printf("Testing KeySet from xml\n"); ks = ksNew(0, KS_END); exit_if_fail( ksFromXMLfile(ks, srcdir_file("xmltool/keyset.xml")) == 0, "ksFromXMLfile(key.xml) failed."); counter = 0; ksRewind(ks); while ( (cur = ksNext(ks)) ) { counter ++; /* Make tests ... */ // printf ("counter: %d - %s\n", counter, keyName(cur)); switch (counter) { // <key type="43" basename="0-27042916" value="0 216905227"><comment>2551516588474823843</comment></key> case 1: succeed_if (strcmp (keyName(cur),"user/tests/filesys/0-27042916") == 0,"name of first key not correct"); succeed_if (strcmp (keyValue(cur),"0 216905227") == 0,"value of first key not correct"); succeed_if (strcmp (keyComment(cur),"2551516588474823843") == 0,"comment of first key not correct"); break; // <key type="253" basename="1-2449524622" value="1 1679328197"><comment>3246436893195629244</comment></key> case 2: succeed_if (strcmp (keyName(cur),"user/tests/filesys/1-2449524622") == 0,"name of 2. key not correct"); succeed_if (strcmp (keyValue(cur),"1 1679328197") == 0,"value of 2. key not correct"); succeed_if (strcmp (keyComment(cur),"3246436893195629244") == 0,"comment of 2. key not correct"); break; // <key type="string" basename="dir-1-0"> case 3: succeed_if (strcmp (keyName(cur),"user/tests/filesys/dir-1-0") == 0,"name of 3. key not correct"); break; // <key type="114" basename="0-294164813" value="0 216245011"><comment>18454108762891828026</comment></key> case 4: succeed_if (strcmp (keyName(cur),"user/tests/filesys/dir-1-0/0-294164813") == 0,"name of 4. key not correct"); succeed_if (strcmp (keyValue(cur),"0 216245011") == 0,"value of 4. key not correct"); succeed_if (strcmp (keyComment(cur),"18454108762891828026") == 0,"comment of 4. key not correct"); break; // <key type="135" basename="1-1479930365" value="1 2732423037"><comment>24597295372375238</comment></key> case 5: succeed_if (strcmp (keyName(cur),"user/tests/filesys/dir-1-0/1-1479930365") == 0,"name of 4. key not correct"); succeed_if (strcmp (keyValue(cur),"1 2732423037") == 0,"value of 4. key not correct"); succeed_if (strcmp (keyComment(cur),"24597295372375238") == 0,"comment of 4. key not correct"); break; // <key type="string" basename="dir-2-0"> case 6: succeed_if (strcmp (keyName(cur),"user/tests/filesys/dir-1-0/dir-2-0") == 0,"name of 3. key not correct"); break; // <key type="144" basename="0-215571059" value="0 264857705"><comment>2188631490667217086</comment></key> case 7: succeed_if (strcmp (keyName(cur),"user/tests/filesys/dir-1-0/dir-2-0/0-215571059") == 0,"name of 4. key not correct"); succeed_if (strcmp (keyValue(cur),"0 264857705") == 0,"value of 4. key not correct"); succeed_if (strcmp (keyComment(cur),"2188631490667217086") == 0,"comment of 4. key not correct"); break; } } ksDel(ks); }
void test_type() { Key *key; succeed_if (key = keyNew(0), "could not create a new key"); succeed_if (keyValue(keyGetMeta(key, "binary")) == 0, "wrong type after key creation"); succeed_if (keySetString (key, "mystring") == sizeof("mystring"), "could not set string"); succeed_if (keyValue(keyGetMeta(key, "binary")) == 0, "wrong type after setting string"); succeed_if (keySetBinary (key, "mystring", sizeof("mystring")) == sizeof("mystring"), "could not set binary"); succeed_if (keyValue(keyGetMeta(key, "binary")) != 0, "wrong type after setting string"); keyDel (key); }
static void test_sectionRead (char * fileName) { Key * parentKey = keyNew ("user/tests/ini-section-read", KEY_VALUE, srcdir_file (fileName), KEY_END); KeySet * conf = ksNew (0, KS_END); PLUGIN_OPEN ("ini"); KeySet * ks = ksNew (0, KS_END); succeed_if (plugin->kdbGet (plugin, ks, parentKey) >= 1, "call to kdbGet was not successful"); succeed_if (output_error (parentKey), "error in kdbGet"); succeed_if (output_warnings (parentKey), "warnings in kdbGet"); Key * key = ksLookupByName (ks, "user/tests/ini-section-read/akey/looking/like/sections", KDB_O_NONE); exit_if_fail (key, "section like key not found not found"); succeed_if (!strcmp ("value", keyString (key)), "section like key contained invalid data"); key = ksLookupByName (ks, "user/tests/ini-section-read/emptysection", KDB_O_NONE); exit_if_fail (key, "empty section key not found"); succeed_if (keyIsBinary (key), "empty section key is not a binary key"); succeed_if (!keyValue (key), "section key contains non null data"); key = ksLookupByName (ks, "user/tests/ini-section-read/section1", KDB_O_NONE); exit_if_fail (key, "section1 key not found"); succeed_if (keyIsBinary (key), "section1 key is not a binary key"); succeed_if (!keyValue (key), "section1 contains non null data"); key = ksLookupByName (ks, "user/tests/ini-section-read/section1/key1", KDB_O_NONE); exit_if_fail (key, "key1 not found not found"); succeed_if (!strcmp ("value1", keyString (key)), "key1 contained invalid data"); key = ksLookupByName (ks, "user/tests/ini-section-read/section1/key/with/subkey", KDB_O_NONE); exit_if_fail (key, "key with subkey not found not found"); succeed_if (!strcmp ("value2", keyString (key)), "key with subkey contained invalid data"); key = ksLookupByName (ks, "user/tests/ini-section-read/section2/with/subkey", KDB_O_NONE); exit_if_fail (key, "section2 key not found"); succeed_if (keyIsBinary (key), "section2 key is not a binary key"); succeed_if (!keyValue (key), "section2 contains non null data"); key = ksLookupByName (ks, "user/tests/ini-section-read/section2/with/subkey/key2", KDB_O_NONE); exit_if_fail (key, "key2 not found not found"); succeed_if (!strcmp ("value2", keyString (key)), "key2 contained invalid data"); ksDel (ks); keyDel (parentKey); PLUGIN_CLOSE (); }
void AsteriskManager::onReadyRead() { QRegExp keyValue("^([A-Za-z0-9\\-]+):\\s(.+)$"); QByteArray line; qDebug("<ami>"); while (canReadLine()) { line = readLine(); qDebug() << line.trimmed(); if (line != "\r\n") { if (keyValue.indexIn(line) > -1) { packetBuffer[keyValue.cap(1)] = stringValue(keyValue.cap(2).trimmed()); } else if (line.startsWith("Asterisk Call Manager")) { version_ = line.replace("Asterisk Call Manager/", QByteArray()).trimmed(); emit connected(version_); } } else if (!packetBuffer.isEmpty()) { dispatchPacket(); } } qDebug("</ami>"); }
/** * Get last time the key metadata was changed from disk. * * @deprecated This API is obsolete. * * You will get 0 when the key was not read already. * * Any changed field in metadata will influence the * ctime of a key. * * This time is not updated if only value * or comment are changed. * * Not changed keys will not update this time, * even after kdbSet(). * * It is possible that other keys written to disc * influence this time if the backend is not grained * enough. * * @param key Key to get information from. * @see keySetCTime() * @retval (time_t)-1 on NULL pointer * @return the metadata change time */ time_t keyGetCTime (const Key * key) { const char * ctime; long int val; char * endptr; int errorval = errno; if (!key) return (time_t)-1; ctime = keyValue (keyGetMeta (key, "ctime")); if (!ctime) return 0; if (*ctime == '\0') return (time_t)-1; /*From now on we have to leave using cleanup*/ errno = 0; val = strtol (ctime, &endptr, 10); /*Check for errors*/ if (errno) goto cleanup; /*Check if nothing was found*/ if (endptr == ctime) goto cleanup; /*Check if the whole string was processed*/ if (*endptr != '\0') goto cleanup; return val; cleanup: /*First restore errno*/ errno = errorval; return (time_t)-1; }
/** Reads the value of the key and decodes all escaping * codes into the buffer. * @pre the buffer needs to be as large as value's size. * @param cur the key holding the value to decode * @param buf the buffer to write to */ void elektraHexcodeDecode (Key * cur, CHexData * hd) { size_t valsize = keyGetValueSize (cur); const char * val = keyValue (cur); if (!val) return; size_t out = 0; for (size_t in = 0; in < valsize - 1; ++in) { char c = val[in]; char * n = hd->buf + out; if (c == hd->escape) { in += 2; /* Advance twice (2 hex numbers) */ char first = val[in - 1]; char second = val[in]; int res; res = elektraHexcodeConvFromHex (second); res += elektraHexcodeConvFromHex (first) * 16; *n = res & 255; } else { *n = c; } ++out; /* Only one char is written */ } hd->buf[out] = 0; // null termination for keyString() keySetRaw (cur, hd->buf, out + 1); }
void test_iterate() { Key *key; key = keyNew ("user/test", KEY_END); exit_if_fail (key, "could not create new key"); succeed_if (keyRewindMeta(key) == 0, "Could not rewind empty key"); succeed_if (keyNextMeta(key) == 0, "Could get next meta name, even if it is empty"); succeed_if (keyCurrentMeta(key) == 0, "Could get next meta value, even if it is empty"); keySetMeta (key, "meta1", "meta_value"); succeed_if (keyRewindMeta(key) == 0, "Could not rewind key"); succeed_if (!strcmp(keyName(keyNextMeta(key)), "meta1"), "keyNextMeta does not work at 1. iteration"); succeed_if (!strcmp(keyValue(keyCurrentMeta(key)), "meta_value"), "keyCurrentMeta does not work at 1. iteration"); succeed_if (keyNextMeta(key) == 0, "Could get next meta name, even if it is empty at 2. iteration"); succeed_if (keyCurrentMeta(key) == 0, "Could get next meta value, even if it is empty at 2. iteration"); succeed_if (keyNextMeta(key) == 0, "Could get next meta name, even if it is empty at 3. iteration"); succeed_if (keyCurrentMeta(key) == 0, "Could get next meta value, even if it is empty at 3. iteration"); succeed_if (keyNextMeta(key) == 0, "Could get next meta name, even if it is empty at 4. iteration"); succeed_if (keyCurrentMeta(key) == 0, "Could get next meta value, even if it is empty at 4. iteration"); keyDel (key); }
void KkrBoardView::keyReleaseEvent(QKeyEvent *e) { switch(e->key()) { case Qt::Key_Up: case Qt::Key_K: case Qt::Key_Down: case Qt::Key_J: case Qt::Key_Left: case Qt::Key_H: case Qt::Key_Right: case Qt::Key_L: keyCursor(e); break; case Qt::Key_S: if(e->modifiers() == Qt::NoModifier) switchCellType(m_curCol, m_curRow); break; case Qt::Key_0: case Qt::Key_1: case Qt::Key_2: case Qt::Key_3: case Qt::Key_4: case Qt::Key_5: case Qt::Key_6: case Qt::Key_7: case Qt::Key_8: case Qt::Key_9: case Qt::Key_Delete: keyValue(e); break; default: // just ignore other keys break; } }
/** Reads the value of the key and encodes it in * c-style in the buffer. * * @param cur the key which value is to encode * @param buf the buffer * @pre the buffer needs to have thrice as much space as the value's size */ void elektraHexcodeEncode (Key * cur, CHexData * hd) { size_t valsize = keyGetValueSize (cur); const char * val = keyValue (cur); if (!val) return; size_t out = 0; for (size_t in = 0; in < valsize - 1; ++in) { unsigned char c = val[in]; // need to encode char? if (hd->hd[c & 255]) { hd->buf[out] = hd->escape; out++; hd->buf[out] = elektraHexcodeConvToHex (c / 16); out++; hd->buf[out] = elektraHexcodeConvToHex (c % 16); out++; } else { // just copy one character hd->buf[out] = val[in]; // advance out cursor out++; } } hd->buf[out] = 0; // null termination for keyString() keySetRaw (cur, hd->buf, out + 1); }
/** * Get the key comment. * * @section comment Comments * * A Key comment is description for humans what this key is for. It may be a * textual explanation of valid values, when and why a user or administrator * changed the key or any other text that helps the user or administrator related * to that key. * * Don't depend on a comment in your program. A user is * always allowed to remove or change it in any way he wants to. But you are * allowed or even encouraged to always show the content of the comment * to the user and allow him to change it. * * @param key the key object to work with * @param returnedComment pre-allocated memory to copy the comments to * @param maxSize number of bytes that will fit returnedComment * @return the number of bytes actually copied to @p returnedString, including * final NULL * @retval 1 if the string is empty * @retval -1 on NULL pointer * @retval -1 if maxSize is 0, not enough to store the comment or when larger then SSIZE_MAX * @see keyGetCommentSize(), keySetComment() */ ssize_t keyGetComment (const Key * key, char * returnedComment, size_t maxSize) { const char * comment; size_t commentSize; if (!key) return -1; if (!maxSize) return -1; if (!returnedComment) return -1; if (maxSize > SSIZE_MAX) return -1; comment = keyValue (keyGetMeta (key, "comment")); commentSize = keyGetValueSize (keyGetMeta (key, "comment")); if (!comment) { /*errno=KDB_ERR_NODESC;*/ returnedComment[0] = 0; return 1; } strncpy (returnedComment, comment, maxSize); if (maxSize < commentSize) { /*errno=KDB_ERR_TRUNC;*/ return -1; } return commentSize; }
static void test_plainIniRead (char * fileName) { Key * parentKey = keyNew ("user/tests/ini-read", KEY_VALUE, srcdir_file (fileName), KEY_END); KeySet * conf = ksNew (0, KS_END); PLUGIN_OPEN ("ini"); KeySet * ks = ksNew (0, KS_END); succeed_if (plugin->kdbGet (plugin, ks, parentKey) >= 1, "call to kdbGet was not successful"); succeed_if (output_error (parentKey), "error in kdbGet"); succeed_if (output_warnings (parentKey), "warnings in kdbGet"); Key * key = ksLookupByName (ks, "user/tests/ini-read/nosectionkey", KDB_O_NONE); exit_if_fail (key, "nosectionkey not found"); succeed_if (!strcmp ("nosectionvalue", keyString (key)), "nosectionkey contained invalid data"); key = ksLookupByName (ks, "user/tests/ini-read/section1", KDB_O_NONE); exit_if_fail (key, "section1 not found"); succeed_if (!keyValue (key), "section value was not empty"); key = ksLookupByName (ks, "user/tests/ini-read/section1/key1", KDB_O_NONE); exit_if_fail (key, "key1 not found"); succeed_if (!strcmp ("value1", keyString (key)), "key1 contained invalid data"); key = ksLookupByName (ks, "user/tests/ini-read/section2/emptykey", KDB_O_NONE); exit_if_fail (key, "emptykey not found"); succeed_if (!strcmp ("", keyString (key)), "emptykey contained invalid data"); ksDel (ks); keyDel (parentKey); PLUGIN_CLOSE (); }
/** * Get the group ID of a key. * * @deprecated This API is obsolete. * * @section GID GID * * The group ID is a unique identification for every group present on * a system. Keys will belong to root (0) as long as you did not get their * real GID with kdbGet(). * * Unlike UID users might change their group. This makes it possible to * share configuration between some users. * * A fresh key will have (gid_t)-1 also known as the group nogroup. * It means that the key is not related to a group ID at the moment. * * @param key the key object to work with * @return the system's GID of the key * @retval (gid_t)-1 on NULL key or currently unknown ID * @see keySetGID(), keyGetUID() */ gid_t keyGetGID (const Key * key) { const char * gid; long int val; char * endptr; int errorval = errno; if (!key) return (gid_t)-1; gid = keyValue (keyGetMeta (key, "gid")); if (!gid) return (gid_t)-1; if (*gid == '\0') return (gid_t)-1; /*From now on we have to leave using cleanup*/ errno = 0; val = strtol (gid, &endptr, 10); /*Check for errors*/ if (errno) goto cleanup; /*Check if nothing was found*/ if (endptr == gid) goto cleanup; /*Check if the whole string was processed*/ if (*endptr != '\0') goto cleanup; return val; cleanup: /*First restore errno*/ errno = errorval; return (gid_t)-1; }
/** * Return the key mode permissions. * * @deprecated This API is obsolete. * * Default is 0664 (octal) for keys and 0775 for directory keys * which used keySetDir(). * * The defaults are defined with the macros KDB_FILE_MODE and KDB_DIR_MODE. * * For more information about the mode permissions see @ref mode. * * @param key the key object to work with * @return mode permissions of the key * @retval KDB_FILE_MODE as defaults * @retval (mode_t)-1 on NULL pointer * @see keySetMode() */ mode_t keyGetMode (const Key * key) { const char * mode; long int val; char * endptr; int errorval = errno; if (!key) return (mode_t)-1; mode = keyValue (keyGetMeta (key, "mode")); if (!mode) return KDB_FILE_MODE; if (*mode == '\0') return KDB_FILE_MODE; /*From now on we have to leave using cleanup*/ errno = 0; val = strtol (mode, &endptr, 8); /*Check for errors*/ if (errno) goto cleanup; /*Check if nothing was found*/ if (endptr == mode) goto cleanup; /*Check if the whole string was processed*/ if (*endptr != '\0') goto cleanup; return val; cleanup: /*First restore errno*/ errno = errorval; return KDB_FILE_MODE; }
/** * @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 getKeyIvForDecryption (KeySet * config, Key * errorKey, Key * masterKey, Key * k, Key * cKey, Key * cIv) { kdb_octet_t keyBuffer[KEY_BUFFER_SIZE]; kdb_octet_t * saltBuffer = NULL; kdb_unsigned_long_t saltBufferLen = 0; ELEKTRA_ASSERT (masterKey != NULL, "Parameter `masterKey` must not be NULL"); // get the salt if (CRYPTO_PLUGIN_FUNCTION (getSaltFromPayload) (errorKey, k, &saltBuffer, &saltBufferLen) != 1) { return -1; // error set by CRYPTO_PLUGIN_FUNCTION(getSaltFromPayload)() } // get the iteration count const kdb_unsigned_long_t iterations = CRYPTO_PLUGIN_FUNCTION (getIterationCount) (errorKey, config); // derive the cryptographic key and the IV pthread_mutex_lock (&mutex_ssl); if (!PKCS5_PBKDF2_HMAC_SHA1 (keyValue (masterKey), keyGetValueSize (masterKey), saltBuffer, saltBufferLen, iterations, KEY_BUFFER_SIZE, keyBuffer)) { ELEKTRA_SET_ERRORF (ELEKTRA_ERROR_CRYPTO_INTERNAL_ERROR, errorKey, "Failed to restore the cryptographic key for decryption. Libcrypto returned the 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; }
static void test_timeoutConnect (void) { printf ("test connect timeout\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); plugin->kdbSet (plugin, ks, parentKey); char * expectedWarningNumber = elektraFormat ("%d", ELEKTRA_WARNING_ZEROMQSEND_TIMEOUT); succeed_if (keyGetMeta (parentKey, "warnings"), "warning meta key was not set"); succeed_if_same_string (expectedWarningNumber, keyValue (keyGetMeta (parentKey, "warnings/#00/number"))); ksDel (ks); keyDel (parentKey); PLUGIN_CLOSE (); elektraFree (expectedWarningNumber); }
/** * @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 getKeyIvForDecryption (KeySet * config, Key * errorKey, Key * masterKey, Key * k, Key * cKey, Key * cIv) { gcry_error_t gcry_err; kdb_octet_t keyBuffer[KEY_BUFFER_SIZE]; kdb_octet_t * saltBuffer = NULL; kdb_unsigned_long_t saltBufferLen = 0; ELEKTRA_ASSERT (masterKey != NULL, "Parameter `masterKey` must not be NULL"); // get the salt if (CRYPTO_PLUGIN_FUNCTION (getSaltFromPayload) (errorKey, k, &saltBuffer, &saltBufferLen) != 1) { return -1; // error set by CRYPTO_PLUGIN_FUNCTION(getSaltFromPayload)() } // get the iteration count const kdb_unsigned_long_t iterations = CRYPTO_PLUGIN_FUNCTION (getIterationCount) (errorKey, config); // derive the cryptographic key and the IV if ((gcry_err = gcry_kdf_derive (keyValue (masterKey), keyGetValueSize (masterKey), GCRY_KDF_PBKDF2, GCRY_MD_SHA512, saltBuffer, saltBufferLen, iterations, KEY_BUFFER_SIZE, keyBuffer))) { ELEKTRA_SET_ERRORF (ELEKTRA_ERROR_CRYPTO_INTERNAL_ERROR, errorKey, "Failed to restore the cryptographic key for decryption because: %s", gcry_strerror (gcry_err)); return -1; } keySetBinary (cKey, keyBuffer, ELEKTRA_CRYPTO_GCRY_KEYSIZE); keySetBinary (cIv, keyBuffer + ELEKTRA_CRYPTO_GCRY_KEYSIZE, ELEKTRA_CRYPTO_GCRY_BLOCKSIZE); return 1; }
void test_otherescape (void) { printf ("test with config with other escape\n"); KeySet * config = ksNew (20, keyNew ("user/chars", KEY_END), keyNew ("user/chars/0A", KEY_VALUE, "6E", KEY_END), // new line -> n keyNew ("user/chars/20", KEY_VALUE, "77", KEY_END), // space -> w keyNew ("user/chars/23", KEY_VALUE, "72", KEY_END), // # -> r keyNew ("user/chars/5C", KEY_VALUE, "62", KEY_END), // \\ (backslash) -> b keyNew ("user/chars/3D", KEY_VALUE, "65", KEY_END), // = -> e keyNew ("user/chars/3B", KEY_VALUE, "73", KEY_END), // ; -> s keyNew ("user/escape", KEY_VALUE, "25", KEY_END), // use % as escape character KS_END); KeySet * returned = ksNew (20, keyNew ("user/something", KEY_VALUE, decoded_string, KEY_END), KS_END); Plugin * p = calloc (1, sizeof (Plugin)); p->config = config; elektraCcodeOpen (p, 0); elektraCcodeSet (p, returned, 0); Key * test = ksLookupByName (returned, "user/something", 0); succeed_if (!memcmp (keyValue (test), other_encoded_string, sizeof (other_encoded_string) - 1), "string not correctly encoded"); elektraCcodeClose (p, 0); ksDel (returned); ksDel (p->config); elektraFree (p); }
int main (void) { Key * k = keyNew ("user/hello", KEY_VALUE, "Hello World", KEY_END); printf ("%s\n", (char *)keyValue (k)); keyDel (k); return 0; }
/** * @internal * * Compare 2 keys. * * The returned flags bit array has 1s (differ) or 0s (equal) for each key * meta info compared, that can be logically ORed using @c #keyswitch_t flags. * @link keyswitch_t::KEY_NAME KEY_NAME @endlink, * @link keyswitch_t::KEY_VALUE KEY_VALUE @endlink, * @link keyswitch_t::KEY_OWNER KEY_OWNER @endlink, * @link keyswitch_t::KEY_COMMENT KEY_COMMENT @endlink, * @link keyswitch_t::KEY_META KEY_META @endlink (will be set in addition to owner and comment), * * @par A very simple example would be * @code Key *key1, *key; uint32_t changes; // omited key1 and key2 initialization and manipulation changes=keyCompare(key1,key2); if (changes == 0) printf("key1 and key2 are identicall\n"); if (changes & KEY_VALUE) printf("key1 and key2 have different values\n"); if (changes & KEY_UID) printf("key1 and key2 have different UID\n"); * * @endcode * * * @par Example of very powerful specific Key lookup in a KeySet: * @code Key *base = keyNew ("/sw/MyApp/something", KEY_END); KDB *handle = kdbOpen(base); KeySet *ks=ksNew(0, KS_END); Key *current; uint32_t match; uint32_t interests; kdbGet(handle, ks, base); // we are interested only in key type and access permissions interests=(KEY_TYPE | KEY_MODE); ksRewind(ks); // put cursor in the beginning while ((curren=ksNext(ks))) { match=keyCompare(current,base); if ((~match & interests) == interests) printf("Key %s has same type and permissions of base key",keyName(current)); // continue walking in the KeySet.... } // now we want same name and/or value interests=(KEY_NAME | KEY_VALUE); // we don't really need ksRewind(), since previous loop achieved end of KeySet ksRewind(ks); while ((current=ksNext(ks))) { match=keyCompare(current,base); if ((~match & interests) == interests) { printf("Key %s has same name, value, and sync status of base key",keyName(current)); } // continue walking in the KeySet.... } ksDel(ks); kdbClose (handle, base); keyDel(base); * @endcode * * @return a bit array pointing the differences * @param key1 first key * @param key2 second key * @see #keyswitch_t * @ingroup keytest */ keyswitch_t keyCompare (const Key * key1, const Key * key2) { if (!key1 && !key2) return 0; if (!key1 || !key2) return KEY_NULL; keyswitch_t ret = 0; ssize_t nsize1 = keyGetNameSize (key1); ssize_t nsize2 = keyGetNameSize (key2); const char * name1 = keyName (key1); const char * name2 = keyName (key2); const Key * comment1 = keyGetMeta (key1, "comment"); const Key * comment2 = keyGetMeta (key2, "comment"); const char * owner1 = keyOwner (key1); const char * owner2 = keyOwner (key2); const void * value1 = keyValue (key1); const void * value2 = keyValue (key2); ssize_t size1 = keyGetValueSize (key1); ssize_t size2 = keyGetValueSize (key2); // TODO: might be (binary) by chance if (strcmp (keyString (comment1), keyString (comment2))) ret |= KEY_COMMENT; if (strcmp (owner1, owner2)) ret |= KEY_OWNER; if (keyCompareMeta (key1, key2)) ret |= KEY_META; if (nsize1 != nsize2) ret |= KEY_NAME; else if (!name1 || !name2) ret |= KEY_NAME; else if (strcmp (name1, name2)) ret |= KEY_NAME; if (size1 != size2) ret |= KEY_VALUE; else if (!value1 || !value2) ret |= KEY_VALUE; else if (memcmp (value1, value2, size1)) ret |= KEY_VALUE; // TODO: rewind metadata to previous position return ret; }
/** * @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; }
int _tmain(int argc, _TCHAR* argv[]) { char a[8]= {'a','b','c','d','e','f','g','h'}; int b[8]= {212,334,432,634,65,76,690,341}; std::vector<char> keyValue(a,a+8); std::vector<int> freqValue(b,b+8); Heap* h=new Heap(keyValue,freqValue); h->HuffManCode(); return 0; }