static void test_keyGetFullName (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 (); succeed_if (plugin->kdbSet (plugin, ks, parentKey) == 1, "kdbSet was not successful"); succeed_if (plugin->kdbGet (plugin, ks, parentKey) == 1, "kdbGet was not successful"); const char * name = "user/tests/storage/a"; Key * found = ksLookupByName (ks, name, 0); succeed_if (found, "did not find key"); ssize_t fullNameSize = keyGetFullNameSize (found); char * fullName = elektraMalloc (fullNameSize); ssize_t ret = keyGetFullName (found, fullName, fullNameSize); if (ret < 1) { yield_error ("Key full name NULL or size error"); } else { succeed_if ((size_t) ret >= elektraStrLen (name), "Key full name size too small"); } elektraFree (fullName); keyDel (parentKey); ksDel (ks); closeStoragePlugin (storagePlugin); }
/** * Same as keyToStream() but tries to strip @p parentSize bytes from * @p key name if it matches @p parent . * * Taking the example from keyToStream(), if @p parent is * @c "system/sw/xorg", the generated string is of the form: * @verbatim <key basename="Monitor/Monitor0/Name" type="string" uid="root" gid="root" mode="0600"> <value>Samsung TFT panel</value> <comment>My monitor</comment> </key>@endverbatim * * It usefull to produce more human readable XML output of a key when * it is being represented in a context that defines the parent key name. * For example: * * @verbatim <keyset parent="user/sw"> <key basename="kdbedit"..../> <key basename="phototools"..../> <key basename="myapp"..../> </keyset>@endverbatim * * In the bove example, each @p @<key@> entry was generated by a call to * keyToStreamBasename() having @c "user/sw" as @p parent . * * This method is used when ksToStream() is called with * KDBOption::KDB_O_HIER option. * * @param key the key object to work with * @param stream the FILE where to send the stream * @param parentSize the maximum size of @p parent that will be used. * If 0, the entire @p parent will be used. * @param parent the string (or part of it, defined by @p parentSize ) that * will be used to strip from the key name. * @param options Some #option_t ORed: * - @p option_t::KDB_O_NUMBERS \n * Do not convert UID and GID into user and group names * - @p option_t::KDB_O_CONDENSED \n * Less human readable, more condensed output * - @p option_t::KDB_O_FULLNAME \n * The @p user keys are exported with their full names (including * user domains) * * @return number of bytes written to output */ ssize_t keyToStreamBasename(const Key *key, FILE *stream, const char *parent, const size_t parentSize, option_t options) { ssize_t written=0; char buffer[KDB_MAX_PATH_LENGTH]; /* Write key name */ if (parent) { /* some logic to see if we should print only the relative basename */ int found; size_t skip=parentSize ? parentSize : elektraStrLen(parent)-1; found=memcmp(parent,key->key,skip); if (found == 0) { while (*(key->key+skip) == KDB_PATH_SEPARATOR) ++skip; if (*(key->key+skip) != 0) /* we don't want a null basename */ written+=fprintf(stream,"<key basename=\"%s\"", key->key+skip); } } if (written == 0) { /* no "<key basename=..." was written so far */ if (options & KDB_O_FULLNAME) { keyGetFullName(key,buffer,sizeof(buffer)); written+=fprintf(stream,"<key name=\"%s\"", buffer); } else written+=fprintf(stream,"<key name=\"%s\"", key->key); } /* Key type TODO: xml schema does not output type if (options & KDB_O_NUMBERS) { written+=fprintf(stream," type=\"%d\"", key->type); } else { buffer[0]=0; if (key->type & KEY_TYPE_DIR) written+=fprintf(stream, " isdir=\"yes\""); if (key->type & KEY_TYPE_REMOVE) written+=fprintf(stream, " isremove=\"yes\""); if (key->type & KEY_TYPE_BINARY) written+=fprintf(stream, " isbinary=\"yes\""); } */ if (keyGetUID (key) != (uid_t)-1) written+=fprintf(stream," uid=\"%d\"", (int)keyGetUID (key)); if (keyGetGID (key) != (gid_t)-1) written+=fprintf(stream," gid=\"%d\"", (int)keyGetGID (key)); if (keyGetMode(key) != KDB_FILE_MODE) { written+=fprintf(stream," mode=\"0%o\"", keyGetMode(key)); } if (!key->data.v && !keyComment(key)) { /* no data AND no comment */ written+=fprintf(stream,"/>"); if (!(options & KDB_O_CONDENSED)) written+=fprintf(stream,"\n\n"); return written; /* end of <key/> */ } else { if (key->data.v) { if ((key->dataSize <= 16) && keyIsString (key) && /*TODO: is this for string?*/ !strchr(key->data.c,'\n')) { /* we'll use a "value" attribute instead of a <value> node, for readability, so the cut size will be 16, which is the maximum size of an IPv4 address */ if (options & KDB_O_CONDENSED) written+=fprintf(stream," "); else written+=fprintf(stream,"\n\t"); written+=fprintf(stream,"value=\"%s\"",key->data.c); if (keyComment(key)) written+=fprintf(stream,">\n"); else { written+=fprintf(stream,"/>"); if (!(options & KDB_O_CONDENSED)) written+=fprintf(stream,"\n"); return written; } } else { /* value is bigger than 16 bytes: deserves own <value> */ written+=fprintf(stream,">"); if (!(options & KDB_O_CONDENSED)) written+=fprintf(stream,"\n\n "); written+=fprintf(stream,"<value>"); if (keyIsString(key)) { /*TODO: is this for string?*/ written+=fprintf(stream,"<![CDATA["); fflush(stream); /* must chop ending \\0 */ written+=fwrite(key->data.v,sizeof(char),key->dataSize-1,stream); written+=fprintf(stream,"]]>"); } else { /* TODO Binary values char *encoded=elektraMalloc(3*key->dataSize); size_t encodedSize; written+=fprintf(stream,"\n"); encodedSize=kdbbEncode(key->data.c,key->dataSize,encoded); fflush(stream); written+=fwrite(encoded,sizeof(char),encodedSize,stream); elektraFree (encoded); written+=fprintf(stream,"\n"); */ } /* fflush(stream); */ written+=fprintf(stream,"</value>"); } } else { /* we have no data */ if (keyComment(key)) { written+=fprintf(stream,">"); if (!(options & KDB_O_CONDENSED)) written+=fprintf(stream,"\n"); } else { written+=fprintf(stream,"/>"); if (!(options & KDB_O_CONDENSED)) written+=fprintf(stream,"\n\n"); return written; } } } if (!(options & KDB_O_CONDENSED)) { written+=fprintf(stream,"\n"); if (keyComment(key)) written+=fprintf(stream," "); } if (keyComment(key)) { written+=fprintf(stream,"<comment><![CDATA[%s]]></comment>", keyComment(key)); if (!(options & KDB_O_CONDENSED)) written+=fprintf(stream,"\n"); } written+=fprintf(stream,"</key>"); if (!(options & KDB_O_CONDENSED)) written+=fprintf(stream,"\n\n"); return written; }