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 (); }
/** * @internal * * Set raw data as the value of a key. * If NULL pointers are passed, key value is cleaned. * This method will not change or set the key type, and should only * be used internally in elektra. * * @param key the key object to work with * @param newBinary array of bytes to set as the value * @param dataSize number bytes to use from newBinary, including the final NULL * @return The number of bytes actually set in internal buffer. * @retval 1 if it was a string which was deleted * @retval 0 if it was a binary which was deleted * @see keySetType(), keySetString(), keySetBinary() * @ingroup keyvalue */ ssize_t keySetRaw(Key *key, const void *newBinary, size_t dataSize) { if (!key) return -1; if (key->flags & KEY_FLAG_RO_VALUE) return -1; if (!dataSize || !newBinary) { if (key->data.v) { elektraFree (key->data.v); key->data.v=0; } key->dataSize = 0; set_bit(key->flags, KEY_FLAG_SYNC); if (keyIsBinary(key)) return 0; return 1; } key->dataSize=dataSize; if (key->data.v) { char *p=0; p=realloc(key->data.v,key->dataSize); if (0==p) return -1; key->data.v=p; } else { char *p=elektraMalloc(key->dataSize); if (0==p) return -1; key->data.v=p; } memcpy(key->data.v,newBinary,key->dataSize); set_bit(key->flags, KEY_FLAG_SYNC); return keyGetValueSize (key); }
/** * Get the value of a key as a binary. * * If the type is not binary -1 will be returned. * * When the binary data is empty (this is not the same as ""!) * 0 will be returned and the returnedBinary will not be changed. * * For string values see keyGetString() and keyIsString(). * * When the returnedBinary is to small to hold the data * (its maximum size is given by maxSize), * the returnedBinary will not be changed and -1 is returned. * * @par Example: * @code Key *key = keyNew ("user/keyname", KEY_TYPE, KEY_TYPE_BINARY, KEY_END); char buffer[300]; if (keyGetBinary(key,buffer,sizeof(buffer)) == -1) { // handle error } * @endcode * * @param key the object to gather the value from * @param returnedBinary pre-allocated memory to store a copy of the key value * @param maxSize number of bytes of pre-allocated memory in @p returnedBinary * @return the number of bytes actually copied to @p returnedBinary * @retval 0 if the binary is empty * @retval -1 on NULL pointers * @retval -1 if maxSize is 0 * @retval -1 if maxSize is too small for string * @retval -1 if maxSize is larger than SSIZE_MAX * @retval -1 on type mismatch: binary expected, but found string * @see keyValue(), keyGetValueSize(), keySetBinary() * @see keyGetString() and keySetString() as preferred alternative to binary * @see keyIsBinary() to see how to check for binary type * @ingroup keyvalue */ ssize_t keyGetBinary(const Key *key, void *returnedBinary, size_t maxSize) { if (!key) return -1; if (!returnedBinary) return -1; if (!maxSize) return -1; if (maxSize > SSIZE_MAX) return -1; if (!keyIsBinary(key)) { /*errno=KDB_ERR_TYPEMISMATCH;*/ return -1; } if (!key->data.v) { return 0; } if (key->dataSize > maxSize) { /*errno=KDB_ERR_TRUNC;*/ return -1; } memcpy(returnedBinary,key->data.v,key->dataSize); return key->dataSize; }
static short isSectionKey(Key *key) { if (!key) return 0; if (keyIsBinary(key)) return 1; else return 0; }
/** * Generate a C-Style key and stream it. * * This keyset can be used to include as c-code for * applikations using elektra. * * @param key the key object to work with * @param stream the file pointer where to send the stream * @param options KDB_O_SHOWINDICES, KDB_O_IGNORE_COMMENT, KDB_O_SHOWINFO * @retval 1 on success * @ingroup stream */ int keyGenerate(const Key * key, FILE *stream, option_t options) { size_t s; char * str; size_t c; char * com; size_t n; char * nam; n = keyGetNameSize (key); if (n>1) { nam = (char*) elektraMalloc (n); if (nam == NULL) return -1; keyGetName (key, nam, n); fprintf(stream,"\tkeyNew (\"%s\"", nam); elektraFree (nam); } s = keyGetValueSize (key); if (s>1) { str = (char*) elektraMalloc (s); if (str == NULL) return -1; if (keyIsBinary(key)) keyGetBinary(key, str, s); else keyGetString (key, str, s); fprintf(stream,", KEY_VALUE, \"%s\"", str); elektraFree (str); } c = keyGetCommentSize (key); if (c>1) { com = (char*) elektraMalloc (c); if (com == NULL) return -1; keyGetComment (key, com, c); fprintf(stream,", KEY_COMMENT, \"%s\"", com); elektraFree (com); } if (! (keyGetMode(key) == 0664 || (keyGetMode(key) == 0775))) { fprintf(stream,", KEY_MODE, 0%3o", keyGetMode(key)); } fprintf(stream,", KEY_END)"); if (options == 0) return 1; /* dummy to make icc happy */ return 1; }
/** * Returns the number of bytes needed to store the key value, including the * NULL terminator. * * It returns the correct size, independent of the Key Type. * If it is a binary there might be '\\0' values in it. * * For an empty string you need one byte to store the ending NULL. * For that reason 1 is returned. This is not true for binary data, * so there might be returned 0 too. * * A binary key has no '\\0' termination. String types have it, so to there * length will be added 1 to have enough space to store it. * * This method can be used with elektraMalloc() before keyGetString() or keyGetBinary() * is called. * * @code char *buffer; buffer = elektraMalloc (keyGetValueSize (key)); // use this buffer to store the value (binary or string) // pass keyGetValueSize (key) for maxSize * @endcode * * @param key the key object to work with * @return the number of bytes needed to store the key value * @retval 1 when there is no data and type is not binary * @retval 0 when there is no data and type is binary * @retval -1 on null pointer * @see keyGetString(), keyGetBinary(), keyValue() * @ingroup keyvalue */ ssize_t keyGetValueSize(const Key *key) { if (!key) return -1; if (!key->data.v) { /*errno=KDB_ERR_NODATA;*/ if (keyIsBinary(key)) return 0; else return 1; } return key->dataSize; }
/** * Return a pointer to the real internal @p key value. * * This is a much more efficient version of keyGetString() * keyGetBinary(), and you should use it if you are responsible enough to * not mess up things. You are not allowed to modify anything * in the returned string. If you need a copy of the Value, consider * to use keyGetString() or keyGetBinary() instead. * * @section string String Handling * * If @p key is string (keyIsString()), you may cast the returned as a * @c "char *" because you'll get a NULL terminated regular string. * * keyValue() returns "" in string mode when there is no value. The reason is * @code key=keyNew(0); keySetString(key,""); keyValue(key); // you would expect "" here keyDel(key); * @endcode * * @section binary Binary Data Handling * * If the data is binary, the size of the value must be determined by * keyGetValueSize(), any strlen() operations are not suitable to determine * the size. * * keyValue() returns 0 in binary mode when there is no value. The reason is * @code key=keyNew(0); keySetBinary(key, 0, 0); keyValue(key); // you would expect 0 here keySetBinary(key,"", 1); keyValue(key); // you would expect "" (a pointer to '\0') here int i=23; keySetBinary(key, (void*)&i, 4); (int*)keyValue(key); // you would expect a pointer to (int)23 here keyDel(key); * @endcode * * @note Note that the Key structure keeps its own size field that is calculated * by library internal calls, so to avoid inconsistencies, you * must never use the pointer returned by keyValue() method to set a new * value. Use keySetString() or keySetBinary() instead. * * @warning Binary keys will return a NULL pointer when there is no data in contrast * to keyName(), keyBaseName(), keyOwner() and keyComment(). For string value the * behaviour is the same. * * @par Example: * @code KDB *handle = kdbOpen(); KeySet *ks=ksNew(0, KS_END); Key *current=0; kdbGetByName(handle,ks,"system/sw/my",KDB_O_SORT|KDB_O_RECURSIVE); ksRewind(ks); while (current=ksNext(ks)) { size_t size=0; if (keyIsBin(current)) { size=keyGetValueSize(current); printf("Key %s has a value of size %d bytes. Value: <BINARY>\nComment: %s", keyName(current), size, keyComment(current)); } else { size=elektraStrLen((char *)keyValue(current)); printf("Key %s has a value of size %d bytes. Value: %s\nComment: %s", keyName(current), size, (char *)keyValue(current), keyComment(current)); } } ksDel (ks); kdbClose (handle); * @endcode * * @param key the key object to work with * @return a pointer to internal value * @retval "" when there is no data and key is not binary * @retval 0 where there is no data and key is binary * @retval 0 on NULL pointer * @see keyGetValueSize(), keyGetString(), keyGetBinary() * @ingroup keyvalue */ const void *keyValue(const Key *key) { if (!key) return 0; if (!key->data.v) { /*errno=KDB_ERR_NOKEY;*/ if (keyIsBinary(key)) return 0; else return ""; } return key->data.v; }
/** * Get the c-string representing the value. * * Will return (null) on null pointers. * Will return (binary) on binary data not ended * with a null byte. * * It is not checked if it is actually a string, * only if it terminates for security reasons. * * @return the c-string of the value * @retval "(null)" on null keys * @retval "" if no data found * @retval "(binary)" on binary keys * @ingroup keyvalue * @param key the key object to get the string from */ const char *keyString(const Key *key) { if (!key) return "(null)"; if (!key->data.c) { return ""; } if (keyIsBinary(key)) { return "(binary)"; } return key->data.c; }
static void test_keyFlags (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 = ksNew (10, keyNew ("user/tests/storage/testKey", KEY_FLAGS, KEY_BINARY, KEY_VALUE, "test key", KEY_END), KS_END); 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, "user/tests/storage/testKey", 0); succeed_if (found, "did not find key"); succeed_if (keyIsBinary (found) == 1, "Key is not binary."); keyDel (parentKey); ksDel (ks); closeStoragePlugin (storagePlugin); }
/** * Generate a C-Style key and stream it. * * This keyset can be used to include as c-code for * applikations using elektra. * * @param key the key object to work with * @param stream the file pointer where to send the stream * @param options KDB_O_SHOWINDICES, KDB_O_IGNORE_COMMENT, KDB_O_SHOWINFO * @retval 1 on success * @ingroup stream */ int keyGenerate (const Key * key, FILE * stream, option_t options) { size_t n = keyGetNameSize (key); if (n > 1) { char * nam = (char *) elektraMalloc (n); if (nam == NULL) return -1; keyGetName (key, nam, n); fprintf (stream, "\tkeyNew (\"%s\"", nam); elektraFree (nam); } size_t s = keyGetValueSize (key); if (s > 1) { char * str = (char *) elektraMalloc (s); if (str == NULL) return -1; if (keyIsBinary (key)) { keyGetBinary (key, str, s); fprintf (stream, ", KEY_SIZE, \"%zd\"", keyGetValueSize (key)); } else { keyGetString (key, str, s); } fprintf (stream, ", KEY_VALUE, \"%s\"", str); elektraFree (str); } const Key * meta; Key * dup = keyDup (key); keyRewindMeta (dup); while ((meta = keyNextMeta (dup))) { fprintf (stream, ", KEY_META, \"%s\", \"%s\"", keyName (meta), keyString (meta)); } keyDel (dup); fprintf (stream, ", KEY_END)"); if (options == 0) return 1; /* dummy to make icc happy */ return 1; }
static void test_enc_and_dec_with_binary() { elektraCryptoHandle *handle; KeySet *config; Key *errorKey = keyNew(KEY_END); const unsigned char original[] = { 0x00, 0x01, 0x02, 0x03 }; unsigned char content[64]; unsigned long read = 0; Key *k = keyNew("user/plugins/crypto/gcrypt/test-enc-dec-bin", KEY_END); keySetBinary(k, original, sizeof(original)); getWorkingConfiguration(&config); succeed_if( elektraCryptoInit(errorKey) == 1, "crypto initialization failed" ); // 1. encrypt succeed_if( elektraCryptoHandleCreate(&handle, config, errorKey) == 1, "handle initialization with compliant config failed" ); succeed_if( elektraCryptoEncrypt(handle, k, errorKey) == 1, "encryption failed" ); elektraCryptoHandleDestroy(handle); // 2. decrypt succeed_if( elektraCryptoHandleCreate(&handle, config, errorKey) == 1, "handle initialization with compliant config failed" ); succeed_if( elektraCryptoDecrypt(handle, k, errorKey) == 1, "decryption failed" ); elektraCryptoHandleDestroy(handle); // 3. check result succeed_if( keyIsBinary(k) == 1, "key is of non-binary type"); read = keyGetBinary(k, content, sizeof(content)); succeed_if( read == sizeof(original), "decrypted value is of different length than original" ); if(read == sizeof(original)) { succeed_if( memcmp(original, content, read) == 0, "decrypted value differs from original"); } keyDel(k); keyDel(errorKey); ksDel(config); elektraCryptoTeardown(); }
void test_key () { KeySet * ks; Key * cur; int counter; printf ("Testing Key from xml\n"); ks = ksNew (0, KS_END); exit_if_fail (ksFromXMLfile (ks, srcdir_file ("xmltool/key.xml")) == 0, "ksFromXMLfile(key.xml) failed."); counter = 0; ksRewind (ks); while ((cur = ksNext (ks))) { counter++; /* Prepend key root */ // snprintf(buf, sizeof(buf), "%s/%s", root, keyName(cur)); // keySetName(cur, buf); /* Make tests ... */ // printf ("counter: %d - name: %s - value: %s\n", counter, (char*) keyName(cur), (char*)keyValue(cur)); switch (counter) { case 1: succeed_if (strcmp (keyName (cur), "user/tests/filesys/.HiddenBinaryKey") == 0, "wrong name"); succeed_if (strcmp (keyValue (cur), "BinaryValue") == 0, "value not correct"); succeed_if (strcmp (keyComment (cur), "Binary key with hidden name") == 0, "comment not correct"); succeed_if (keyIsInactive (cur) == 1, "key is inactive"); succeed_if (keyIsBinary (cur) == 1, "key is not binary"); succeed_if (keyGetMode (cur) == 0440, "could not get mode"); break; case 2: succeed_if (strcmp (keyName (cur), "user/tests/filesys/.HiddenDirectoryKey") == 0, "wrong name"); succeed_if (strcmp (keyValue (cur), "DirectoryValue") == 0, "value not correct"); succeed_if (strcmp (keyComment (cur), "Directory key with hidden name") == 0, "comment not correct"); succeed_if (keyIsInactive (cur) == 1, "key is inactive"); succeed_if (keyIsString (cur) == 1, "key is not string"); break; case 3: succeed_if (strcmp (keyName (cur), "user/tests/filesys/.HiddenStringKey") == 0, "wrong name"); succeed_if (strcmp (keyValue (cur), "StringValue") == 0, "value not correct"); succeed_if (strcmp (keyComment (cur), "String key with hidden name") == 0, "comment not correct"); succeed_if (keyIsInactive (cur) == 1, "key is inactive"); succeed_if (keyIsString (cur) == 1, "key is not string"); succeed_if (keyGetUID (cur) == 0, "could not get uid value"); succeed_if (keyGetGID (cur) == 20, "could not get gid value"); break; case 4: succeed_if (strcmp (keyName (cur), "user/tests/filesys/PerfectBinaryKey") == 0, "wrong name"); succeed_if (strcmp (keyValue (cur), "BinaryValue") == 0, "value not correct"); succeed_if (strcmp (keyComment (cur), "Binary key with standard name") == 0, "comment not correct"); succeed_if (keyIsInactive (cur) == 0, "key is active"); succeed_if (keyIsBinary (cur) == 1, "key is not binary"); succeed_if (keyGetGID (cur) == 40, "could not get gid value"); break; case 5: succeed_if (strcmp (keyName (cur), "user/tests/filesys/PerfectDirectoryKey") == 0, "wrong name"); succeed_if (strcmp (keyValue (cur), "DirectoryValue") == 0, "value not correct"); succeed_if (strcmp (keyComment (cur), "Directory key with standard name") == 0, "comment not correct"); succeed_if (keyIsInactive (cur) == 0, "key is active"); succeed_if (keyIsString (cur) == 1, "key is not string"); break; case 6: succeed_if (strcmp (keyName (cur), "user/tests/filesys/PerfectStringKey") == 0, "wrong name"); succeed_if (strcmp (keyValue (cur), "StringValue") == 0, "value not correct"); succeed_if (strcmp (keyComment (cur), "String key with\nstandard name") == 0, "comment not correct"); succeed_if (keyIsInactive (cur) == 0, "key is active"); succeed_if (keyIsString (cur) == 1, "key is not string"); succeed_if (keyGetUID (cur) == 20, "could not get uid value"); break; case 7: succeed_if (strcmp (keyName (cur), "user/tests/filesys/Ug.ly:Bin@a€ry Key") == 0, "wrong name"); succeed_if (keyValue (cur) == 0, "value not correct"); succeed_if (strcmp (keyComment (cur), "Binary key with ugly name") == 0, "comment not correct"); succeed_if (keyIsInactive (cur) == 0, "key is active"); succeed_if (keyIsBinary (cur) == 1, "key is not binary"); succeed_if (keyGetMode (cur) == 230, "could not get mode"); // <key type="binary" basename="Ug.ly:Bin@a€ry Key"><comment>Binary key with ugly name</comment></key> break; case 8: succeed_if (strcmp (keyName (cur), "user/tests/filesys/Ug.ly:Dir@ect€ory Key") == 0, "wrong name"); succeed_if (strcmp (keyValue (cur), "") == 0, "value not correct"); succeed_if (strcmp (keyComment (cur), "Directory with ugly name") == 0, "comment not correct"); succeed_if (keyIsInactive (cur) == 0, "key is active"); succeed_if (keyIsString (cur) == 1, "key is not string"); // <key type="directory" basename="Ug.ly:Dir@ect€ory Key"><comment>Directory with ugly name</comment></key> break; case 9: succeed_if (strcmp (keyName (cur), "user/tests/filesys/Ug.ly:St@ri€n.g Key") == 0, "wrong name"); succeed_if (strcmp (keyValue (cur), "With a string value") == 0, "value not correct"); succeed_if (strcmp (keyComment (cur), "string key with ugly name") == 0, "comment not correct"); succeed_if (keyIsInactive (cur) == 0, "key is active"); succeed_if (keyIsString (cur) == 1, "key is not string"); // <key type="string" basename="Ug.ly:St@ri€n.g Key" value="With a string value"><comment>string key with ugly // name</comment></key> break; } } ksDel (ks); }
/* * Processes the current <key> node from reader, converting from XML * to a Key object, and ksAppendKey() it to ks. * * See keyToStream() for an example of a <key> node. * * This function is completelly dependent on libxml. * * @param ks where to put the resulting reded key * @param context a prent key name, so a full name can be calculated * if the XML node for the current key only provides a basename * @param reader where to read from */ static int consumeKeyNode(KeySet *ks, const char *context, xmlTextReaderPtr reader) { xmlChar *nodeName=0; xmlChar *keyNodeName=0; xmlChar *buffer=0; xmlChar *privateContext=0; Key *newKey=0; int appended=0; /* printf("%s", KDB_SCHEMA_PATH); */ keyNodeName=xmlTextReaderName(reader); if (!strcmp((char *)keyNodeName,"key")) { mode_t isdir=0; int isbin=0; int end=0; newKey=keyNew(0); /* a <key> must have one of the following: - a "name" attribute, used as an absolute name overriding the context - a "basename" attribute, that will be appended to the current context - a "parent" plus "basename" attributes, both appended to current context - only a "parent", appended to current context */ buffer=xmlTextReaderGetAttribute(reader,(const xmlChar *)"name"); if (buffer) { /* set absolute name */ keySetName(newKey,(char *)buffer); xmlFree(buffer); buffer=0; } else { /* logic for relative name calculation */ privateContext=xmlTextReaderGetAttribute(reader, (const xmlChar *)"parent"); buffer=xmlTextReaderGetAttribute(reader, (const xmlChar *)"basename"); if (context) keySetName(newKey,context); if (privateContext) keyAddName(newKey, (char *)privateContext); if (buffer) keyAddName(newKey,(char *)buffer); xmlFree(privateContext); privateContext=0; xmlFree(buffer); buffer=0; } /* test for a short value attribute, instead of <value> bellow */ buffer=xmlTextReaderGetAttribute(reader,(const xmlChar *)"value"); if (buffer) { keySetRaw(newKey,buffer,elektraStrLen((char *)buffer)); xmlFree(buffer); buffer=0; } /* Parse UID */ buffer=xmlTextReaderGetAttribute(reader,(const xmlChar *)"uid"); if (buffer) { int errsave = errno; char * endptr; long int uid = strtol ((const char *)buffer, &endptr, 10); errno = errsave; if (endptr != '\0' && *endptr == '\0') { keySetUID(newKey,uid); } xmlFree(buffer); buffer=0; } /* Parse GID */ buffer=xmlTextReaderGetAttribute(reader,(const xmlChar *)"gid"); if (buffer) { int errsave = errno; char * endptr; long int gid = strtol ((const char *)buffer, &endptr, 10); errno = errsave; if (endptr != '\0' && *endptr == '\0') { keySetGID(newKey,gid); } xmlFree(buffer); buffer=0; } /* Parse mode permissions */ buffer=xmlTextReaderGetAttribute(reader,(const xmlChar *)"mode"); int errsave = errno; if (buffer) keySetMode(newKey,strtol((char *)buffer,0,0)); errno = errsave; xmlFree(buffer); if (xmlTextReaderIsEmptyElement(reader)) { /* we have a <key ..../> element */ if (newKey && !appended) { ksAppendKey(ks,newKey); appended=1; end=1; } } buffer=xmlTextReaderGetAttribute(reader,(const xmlChar *)"type"); if (buffer) { if (!strcmp((char *)buffer,"binary")) isbin = 1; else if (!strcmp((char *)buffer,"bin")) isbin = 1; } xmlFree(buffer); /* If "isdir" appears, everything different from "0", "false" or "no" marks it as a dir key */ buffer=xmlTextReaderGetAttribute(reader,(const xmlChar *)"isdir"); if (!isdir && buffer) { if ( strcmp((char *)buffer,"0") && strcmp((char *)buffer,"false") && strcmp((char *)buffer,"no")) isdir = 1; else isdir = 0; } xmlFree(buffer); if (isdir) keySetDir(newKey); if (isbin) keySetMeta (newKey, "binary", ""); // TODO: should parse arbitrary attributes as metadata /* Parse everything else */ while (!end) { xmlTextReaderRead(reader); nodeName=xmlTextReaderName(reader); if (!strcmp((char *)nodeName,"value")) { if (xmlTextReaderIsEmptyElement(reader) || xmlTextReaderNodeType(reader)==15) { xmlFree (nodeName); continue; } xmlTextReaderRead(reader); buffer=xmlTextReaderValue(reader); if (buffer) { /* Key's value type was already set above */ if (keyIsBinary(newKey)) { /* TODO binary values char *unencoded=0; size_t unencodedSize; unencodedSize=elektraStrLen((char *)buffer)/2; unencoded=elektraMalloc(unencodedSize); unencodedSize=kdbbDecode((char *)buffer,unencoded); if (!unencodedSize) return -1; keySetRaw(newKey,unencoded,unencodedSize); elektraFree (unencoded); */ } else keySetRaw(newKey,buffer,elektraStrLen((char *)buffer)); } xmlFree(buffer); } else if (!strcmp((char *)nodeName,"comment")) { ssize_t commentSize=0; if (xmlTextReaderIsEmptyElement(reader) || xmlTextReaderNodeType(reader)==15) { xmlFree (nodeName); continue; } xmlTextReaderRead(reader); buffer=xmlTextReaderValue(reader); if ((commentSize=keyGetCommentSize(newKey)) > 1) { /*Multiple line comment*/ char *tmpComment=0; tmpComment=elektraMalloc(commentSize+ xmlStrlen(buffer)*sizeof(xmlChar)+1); if (tmpComment) { keyGetComment(newKey,tmpComment,commentSize); strcat(tmpComment,"\n"); strcat(tmpComment,(char *)buffer); keySetComment(newKey,tmpComment); elektraFree (tmpComment); tmpComment=0; } } else keySetComment(newKey,(char *)buffer); xmlFree(buffer); } else if (!strcmp((char *)nodeName,"key")) { /* Here we found </key> or a sub <key>. So include current key in the KeySet. */ if (newKey && !appended) { ksAppendKey(ks,newKey); appended=1; } if (xmlTextReaderNodeType(reader)==15) /* found a </key> */ end=1; else { /* found a sub <key> */ /* prepare the context (parent) */ consumeKeyNode(ks,newKey->key,reader); } } xmlFree (nodeName); } if (privateContext) xmlFree(privateContext); /* seems like we forgot the key, lets delete it */ if (newKey && !appended) { keyDel (newKey); appended=1; } } xmlFree(keyNodeName); return 0; }
/** * Output every information of a single key depending on options. * * The format is not very strict and only intend to be read * by human eyes for debugging purposes. Don't rely on the * format in your applications. * * @param k the key object to work with * @param stream the file pointer where to send the stream * @param options see text above * @see ksOutput() * @retval 1 on success * @retval -1 on allocation errors * @ingroup stream */ int keyOutput (const Key * k, FILE *stream, option_t options) { time_t t; size_t s; char * tmc; char * str; size_t c; char * com; size_t n; char * nam; n = keyGetNameSize (k); if (n>1) { nam = (char*) elektraMalloc (n); if (nam == NULL) return -1; keyGetName (k, nam, n); fprintf(stream,"Name[%d]: %s : ", (int)n, nam); elektraFree (nam); } s = keyGetValueSize (k); if (options & KEY_VALUE && s>1) { str = (char*) elektraMalloc (s); if (str == NULL) return -1; if (keyIsBinary(k)) { /* char * bin; bin = (char*) elektraMalloc (s*3+1); keyGetBinary(k, str, s); kdbbEncode (str, s, bin); elektraFree (bin); */ keyGetBinary (k, str, s); fprintf(stream,"Binary[%d]: %s : ", (int)s, str); } else { keyGetString (k, str, s); fprintf(stream,"String[%d]: %s : ", (int)s, str); } elektraFree (str); } c = keyGetCommentSize (k); if (options & KEY_COMMENT && c>1) { com = (char*) elektraMalloc (c); if (com == NULL) return -1; keyGetComment (k, com, c); fprintf(stream,"Comment[%d]: %s : ", (int)c, com); elektraFree (com); } if (options & KDB_O_SHOWMETA) fprintf(stream," : "); if (options & KEY_UID) fprintf(stream,"UID: %d : ", (int)keyGetUID (k)); if (options & KEY_GID) fprintf(stream,"GID: %d : ", (int)keyGetGID (k)); if (options & KEY_MODE) fprintf(stream,"Mode: %o : ", (int)keyGetMode (k)); if (options & KEY_ATIME) { t=keyGetATime(k); tmc = ctime (& t); tmc[24] = '\0'; fprintf(stream,"ATime: %s : ", tmc); } if (options & KEY_MTIME) { t=keyGetMTime(k); tmc = ctime (& t); tmc[24] = '\0'; fprintf(stream,"MTime: %s : ", tmc); } if (options & KEY_CTIME) { t=keyGetCTime(k); tmc = ctime (& t); tmc[24] = '\0'; fprintf(stream,"CTime: %s : ", tmc); } if (options & KDB_O_SHOWFLAGS) { if (!(options & KDB_O_SHOWMETA)) fprintf(stream, " "); fprintf (stream,"Flags: "); if (keyIsBinary(k)) fprintf(stream,"b"); if (keyIsString(k)) fprintf(stream,"s"); if (keyIsInactive(k)) fprintf(stream,"i"); if (keyNeedSync(k)) fprintf(stream,"s"); } fprintf(stream,"\n"); return 1; }