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);
}
示例#2
0
文件: stream.c 项目: tryge/libelektra
/**
 * 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;
}