예제 #1
0
파일: keytest.c 프로젝트: intfrr/libelektra
/**
 * 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;
}
예제 #2
0
static void elektraDropCurrentKey (KeySet * ks, Key * warningKey, const Backend * curHandle, const char * msg)
{
	const Key * k = ksCurrent (ks);

	const size_t sizeOfStaticText = 100;
	char * warningMsg = elektraMalloc (keyGetNameSize (curHandle->mountpoint) + keyGetValueSize (curHandle->mountpoint) +
					   keyGetNameSize (k) + strlen (msg) + sizeOfStaticText);
	strcpy (warningMsg, "drop key ");
	const char * name = keyName (k);
	if (name)
	{
		strcat (warningMsg, name);
	}
	else
	{
		strcat (warningMsg, "(no name)");
	}
	strcat (warningMsg, " not belonging to ");
	strcat (warningMsg, keyName (curHandle->mountpoint));
	strcat (warningMsg, " with name ");
	strcat (warningMsg, keyString (curHandle->mountpoint));
	strcat (warningMsg, " because ");
	strcat (warningMsg, msg);
	ELEKTRA_ADD_WARNING (79, warningKey, warningMsg);
	elektraFree (warningMsg);
	cursor_t c = ksGetCursor (ks);
	keyDel (elektraKsPopAtCursor (ks, c));
	ksSetCursor (ks, c);
	elektraKsPrev (ks); // next ksNext() will point correctly again
}
예제 #3
0
// keyRel2 helper, turns key into a cascading key ( removes namespace)
Key * keyAsCascading (const Key * key)
{
	if (keyName (key)[0] == '/')
	{
		return keyDup (key);
	}
	else
	{
		const char * name = keyName (key);
		const char * ptr = strchr (name, '/');
		if (!ptr)
		{
			return keyNew ("/", KEY_CASCADING_NAME, KEY_END);
		}
		else
		{
			ssize_t length = keyGetNameSize (key);
			if ((ptr - name) == (length - 1))
			{
				return keyNew ("/", KEY_CASCADING_NAME, KEY_END);
			}
			else
			{
				return keyNew (ptr, KEY_CASCADING_NAME, KEY_END);
			}
		}
	}
}
예제 #4
0
static KeySet * getGlobKeys (Key * parentKey, KeySet * keys, enum GlobDirection direction)
{
	KeySet * glob = ksNew (0, KS_END);
	Key * k = 0;
	size_t parentsize = keyGetNameSize (parentKey);

	Key * userGlobConfig = 0;
	Key * systemGlobConfig = 0;
	Key * userDirGlobConfig = 0;
	Key * systemDirGlobConfig = 0;

	userGlobConfig = keyNew ("user/glob", KEY_END);
	systemGlobConfig = keyNew ("system/glob", KEY_END);
	switch (direction)
	{
	case GET:
		userDirGlobConfig = keyNew ("user/glob/get", KEY_END);
		systemDirGlobConfig = keyNew ("system/glob/get", KEY_END);
		break;
	case SET:
		userDirGlobConfig = keyNew ("user/glob/set", KEY_END);
		systemDirGlobConfig = keyNew ("system/glob/set", KEY_END);
		break;
	}

	while ((k = ksNext (keys)) != 0)
	{
		/* use only glob keys for the current direction */
		if (keyIsDirectBelow (userGlobConfig, k) || keyIsDirectBelow (systemGlobConfig, k) ||
		    keyIsDirectBelow (userDirGlobConfig, k) || keyIsDirectBelow (systemDirGlobConfig, k))
		{
			keySetMeta (k, "glob/flags", getGlobFlags (keys, k));

			/* Look if we have a string */
			size_t valsize = keyGetValueSize (k);
			if (valsize < 2) continue;

			/* We now know we want that key.
			 Dup it to not change the configuration. */
			Key * ins = keyDup (k);
			/* Now look if we want cascading for the key */
			if (keyString (k)[0] == '/')
			{
				char * newstring = elektraMalloc (valsize + parentsize);
				strcpy (newstring, keyName (parentKey));
				strcat (newstring, keyString (k));
				keySetString (ins, newstring);
				elektraFree (newstring);
			}
			ksAppendKey (glob, ins);
		}
	}

	keyDel (userGlobConfig);
	keyDel (systemGlobConfig);
	keyDel (userDirGlobConfig);
	keyDel (systemDirGlobConfig);

	return glob;
}
예제 #5
0
파일: filename.c 프로젝트: tryge/libelektra
static int elektraResolveEnvUser(resolverHandle *p)
{
	const char* owner = getenv("USER");

	if (!owner || !strcmp(owner, ""))
	{
		return 0;
	}

	Key *canonify = keyNew("user", KEY_END);
	keyAddName(canonify, owner);
	size_t dirnameSize = sizeof(KDB_DB_HOME "/")
			+ keyGetNameSize(canonify)
			+ sizeof("/" KDB_DB_USER);

	p->dirname= elektraMalloc (dirnameSize);
	strcpy (p->dirname, KDB_DB_HOME "/");
	strcat (p->dirname, keyName(canonify)
			+5); // cut user/
	if (p->path[0] != '/')
	{
		strcat (p->dirname, "/" KDB_DB_USER);
	}
	keyDel(canonify);

	return 1;
}
예제 #6
0
파일: proposal.c 프로젝트: beku/libelektra
/**
 * @brief Takes the first key and cuts off this common part
 * for all other keys, instead name will be prepended
 *
 * @return a new allocated keyset with keys in user namespace.
 *
 * The first key is removed in the resulting keyset.
 */
KeySet* elektraRenameKeys(KeySet *config, const char* name)
{
	Key *root;
	Key *cur;
	ssize_t rootSize = 0;

	ksRewind(config);

	root = ksNext (config);
	rootSize = keyGetNameSize(root);

	keyDel (ksLookup (config, root, KDB_O_POP));

	KeySet *newConfig = ksNew(ksGetSize(config), KS_END);
	if (rootSize == -1) return newConfig;

	while ((cur = ksPop(config)) != 0)
	{
		Key *dupKey = keyDup(cur);
		keySetName(dupKey, name);
		keyAddName(dupKey, keyName(cur)+rootSize-1);
		ksAppendKey(newConfig, dupKey);
		keyDel(cur);
	}

	return newConfig;
}
예제 #7
0
static void test_lookupNoascading ()
{
	printf ("Test lookup without cascading\n");

	Key * specKey = keyNew ("/abc", KEY_CASCADING_NAME, KEY_END);

	Key * d = keyDup (specKey);
	keySetString (d, "dup");
	succeed_if_same_string (keyName (specKey), "/abc");
	succeed_if_same_string (keyName (d), "/abc");

	succeed_if (!keyCmp (d, specKey), "comparision to duplicate failed");
	succeed_if_same_string (keyName (d), "/abc");
	succeed_if_same_string (keyName (specKey), "/abc");

	KeySet * ks = ksNew (20, d, KS_END);

	Key * k = ksLookup (ks, specKey, KDB_O_NOCASCADING);
	succeed_if_same_string (keyName (specKey), "/abc");
	succeed_if (k != 0, "did not find cascading key");
	succeed_if (k != specKey, "should not be specKey");
	succeed_if (k == d, "should be dup key");

	Key * a = keyNew (keyName (specKey), KEY_CASCADING_NAME, KEY_VALUE, "a", KEY_END);
	ksAppendKey (ks, a);

	for (int i = 0; i < 5; ++i)
	{
		k = ksLookup (ks, specKey, KDB_O_NOCASCADING);
		succeed_if (keyGetNameSize (specKey) == 5, "size of spec key wrong");
		succeed_if_same_string (keyName (specKey), "/abc");
		succeed_if (k != 0, "did not find cascading key");
		succeed_if (k != specKey, "should not be specKey");
		succeed_if (k == a, "should be dup key");

		// search without cascading
		k = ksLookup (ks, specKey, 0);
		succeed_if (keyGetNameSize (specKey) == 5, "size of spec key wrong");
		succeed_if_same_string (keyName (specKey), "/abc");
		succeed_if (k != 0, "did not find cascading key");
		succeed_if (k != specKey, "should not be specKey");
		succeed_if (k == a, "should be dup key");
	}

	ksDel (ks);
	keyDel (specKey);
}
예제 #8
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;
}
예제 #9
0
static int saveTree (augeas * augeasHandle, KeySet * ks, const char * lensPath, Key * parentKey)
{
	int ret = 0;

	size_t prefixSize = keyGetNameSize (parentKey) - 1;
	size_t arraySize = ksGetSize (ks);
	Key ** keyArray = calloc (ksGetSize (ks), sizeof (Key *));
	ret = elektraKsToMemArray (ks, keyArray);

	if (ret < 0) goto memoryerror;

	qsort (keyArray, arraySize, sizeof (Key *), keyCmpOrderWrapper);

	/* convert the Elektra KeySet to an Augeas tree */
	for (size_t i = 0; i < arraySize; i++)
	{
		Key * key = keyArray[i];
		char * nodeName;
		ret = asprintf (&nodeName, AUGEAS_TREE_ROOT "%s", (keyName (key) + prefixSize));

		if (ret < 0) goto memoryerror;

		aug_set (augeasHandle, nodeName, keyString (key));
		elektraFree (nodeName);
	}

	elektraFree (keyArray);

	/* remove keys not present in the KeySet */
	struct OrphanSearch * data = elektraMalloc (sizeof (struct OrphanSearch));

	if (!data) return -1;

	data->ks = ks;
	data->parentKey = parentKey;

	ret = foreachAugeasNode (augeasHandle, AUGEAS_TREE_ROOT, &removeOrphan, data);

	elektraFree (data);

	/* build the tree */
	ret = aug_text_retrieve (augeasHandle, lensPath, AUGEAS_CONTENT_ROOT, AUGEAS_TREE_ROOT, AUGEAS_OUTPUT_ROOT);

	if (ret < 0)
	{
		/* report the augeas specific error */
		ELEKTRA_SET_ERROR (85, parentKey, getAugeasError (augeasHandle));
	}

	return ret;

memoryerror:
	elektraFree (keyArray);
	ELEKTRA_SET_ERROR (87, parentKey, "Unable to allocate memory while saving the augeas tree");
	return -1;
}
예제 #10
0
파일: keytest.c 프로젝트: intfrr/libelektra
/**
 * Check if the key check is below the key key or not.
 *
 * Example:
@verbatim
key user/sw/app
check user/sw/app/key
@endverbatim
 *
 * returns true because check is below key
 *
 * Example:
@verbatim
key user/sw/app
check user/sw/app/folder/key
@endverbatim
 *
 * returns also true because check is indirect below key
 *
 * @param key the key object to work with
 * @param check the key to find the relative position of
 * @return 1 if check is below key
 * @return 0 if it is not below or if it is the same key
 * @see keySetName(), keyGetName(), keyIsDirectBelow()
 * @ingroup keytest
 *
 */
int keyIsBelow(const Key *key, const Key *check)
{
	const char * keyname = 0;
	const char * checkname = 0;
	ssize_t keysize = 0;
	ssize_t checksize = 0;

	if (!key || !check) return -1;

	keyname = keyName(key);
	checkname = keyName(check);
	keysize = keyGetNameSize(key);
	checksize = keyGetNameSize(check);

	if (keysize > checksize + 1) return 0;
	if (strncmp (keyname, checkname, keysize - 1)) return 0;
	if (checkname[keysize - 1] != '/') return 0;
	return 1;
}
예제 #11
0
파일: stream.c 프로젝트: tryge/libelektra
/**
 * 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;
}
예제 #12
0
파일: keytest.c 프로젝트: intfrr/libelektra
/**
 * Check if the key check is direct below the key key or not.
 *
@verbatim
Example:
key user/sw/app
check user/sw/app/key

returns true because check is below key

Example:
key user/sw/app
check user/sw/app/folder/key

does not return true, because there is only a indirect relation
@endverbatim
 *
 * @param key the key object to work with
 * @param check the key to find the relative position of
 * @return 1 if check is below key
 * @return 0 if it is not below or if it is the same key
 * @return -1 on null pointer
 * @see keyIsBelow(), keySetName(), keyGetName()
 * @ingroup keytest
 *
 */
int keyIsDirectBelow(const Key *key, const Key *check)
{
	const char * checkname = 0;
	ssize_t keysize = 0;

	if (!key || !check) return -1;

	checkname = keyName(check);
	keysize = keyGetNameSize(key);

	if (!keyIsBelow(key, check)) return 0;
	if (strchr(checkname + keysize, '/')) return 0;
	return 1;
}
예제 #13
0
/**
 * @brief get relative position of key based on parentKey
 *
 * @param cur the key below parentKey we want to get the relative basename of
 * @param parentKey the key that defines the root/base
 *
 * @return a pointer to the name of the key cur
 */
const char * elektraKeyGetRelativeName (Key const * cur, Key const * parentKey)
{
	size_t offset = 0;

	if (strcmp (keyName (parentKey), "/"))
	{
		offset = keyGetNameSize (parentKey);
		if (keyName (parentKey)[0] == '/' && keyName (cur)[0] != '/')
		{
			offset += strstr (keyName (cur), keyName (parentKey)) - keyName (cur);
		}
	}
	return keyName (cur) + offset;
}
예제 #14
0
파일: augeas.c 프로젝트: beku/libelektra
static int saveTree(augeas* augeasHandle, KeySet* ks, const char* lensPath,
		Key *parentKey)
{
	int ret = 0;

	size_t prefixSize = keyGetNameSize (parentKey) - 1;
	size_t arraySize = ksGetSize (ks);
	Key **keyArray = calloc (ksGetSize(ks), sizeof (Key *));
	ret = elektraKsToMemArray (ks, keyArray);

	if (ret < 0)
	{
		free (keyArray);
		return -1;
	}

	qsort (keyArray, arraySize, sizeof(Key *), keyCmpOrderWrapper);

	/* convert the Elektra KeySet to an Augeas tree */
	for (size_t i = 0; i < arraySize; i++)
	{
		Key *key = keyArray[i];
		char *nodeName;
		asprintf (&nodeName, AUGEAS_TREE_ROOT "%s",
				(keyName (key) + prefixSize));
		aug_set (augeasHandle, nodeName, keyString (key));
		free (nodeName);
	}

	free (keyArray);

	/* remove keys not present in the KeySet */
	struct OrphanSearch *data = malloc (sizeof(struct OrphanSearch));

	if (!data) return -1;

	data->ks = ks;
	data->parentKey = parentKey;

	foreachAugeasNode (augeasHandle, AUGEAS_TREE_ROOT, &removeOrphan, data);

	free (data);

	/* build the tree */
	ret = aug_text_retrieve (augeasHandle, lensPath, AUGEAS_CONTENT_ROOT,
	AUGEAS_TREE_ROOT, AUGEAS_OUTPUT_ROOT);

	return ret;
}
예제 #15
0
static void elektraResolveUsingHome (ElektraResolved * handle, const char * home, short addPostfix)
{
	Key * canonify = keyNew ("user", KEY_END);
	keyAddName (canonify, home);

	size_t dirnameSize = keyGetNameSize (canonify) + sizeof ("/" KDB_DB_USER);
	char * dir = elektraMalloc (dirnameSize);

	strcpy (dir, keyName (canonify) + 4); // cut user, leave slash
	if (addPostfix && handle->relPath[0] != '/')
	{
		strcat (dir, "/" KDB_DB_USER);
	}
	handle->dirname = dir;
	keyDel (canonify);
}
예제 #16
0
static void elektraResolveUsingHome (resolverHandle * p, const char * home, bool addPostfix)
{
	size_t dirnameSize = 0;
	Key * canonify = keyNew ("user", KEY_END);

	keyAddName (canonify, home);

	dirnameSize = keyGetNameSize (canonify) + sizeof ("/" KDB_DB_USER);
	p->dirname = elektraMalloc (dirnameSize);
	strcpy (p->dirname, keyName (canonify) + 4); // cut user, but leave slash
	if (addPostfix && p->path[0] != '/')
	{
		strcat (p->dirname, "/" KDB_DB_USER);
	}
	keyDel (canonify);
}
예제 #17
0
파일: c.c 프로젝트: sanssecours/libelektra
/**
 * 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;
}
예제 #18
0
파일: trie.c 프로젝트: beku/libelektra
/**
 * 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;
}
예제 #19
0
static void test_keyName (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 nameSize = keyGetNameSize (found);
	succeed_if (elektraStrNCmp (name, keyName (found), nameSize) == 0, "wrong Key name");

	keyDel (parentKey);
	ksDel (ks);
	closeStoragePlugin (storagePlugin);
}
예제 #20
0
파일: augeas.c 프로젝트: beku/libelektra
static Key *createKeyFromPath(Key *parentKey, const char *treePath)
{
	Key *key = keyDup (parentKey);
	const char *baseName = (treePath + strlen (AUGEAS_TREE_ROOT) + 1);

	size_t baseSize = keyGetNameSize(key);
	size_t keyNameSize = strlen (baseName) + baseSize + 1;
	char *newName = malloc (keyNameSize);

	if (!newName) return 0;

	strcpy (newName, keyName (key));
	newName[baseSize - 1] = KDB_PATH_SEPARATOR;
	newName[baseSize] = 0;
	strcat (newName, baseName);

	keySetName(key, newName);
	free (newName);

	return key;
}
예제 #21
0
// keyRel2 helper, turns key into a cascading key ( removes namespace)
Key * keyAsCascading (const Key * key)
{
	if (keyName (key)[0] == '/')
	{
		return keyDup (key);
	}
	else
	{
		elektraNamespace ns = keyGetNamespace (key);
		if (ns == KEY_NS_META || ns == KEY_NS_EMPTY || ns == KEY_NS_NONE)
		{
			// For metakeys or keys without namespace just prefix the keyname with a "/"
			Key * cKey = keyNew ("/", KEY_CASCADING_NAME, KEY_END);
			keyAddName (cKey, keyName (key));
			return cKey;
		}
		else
		{
			// Skip namespace
			const char * name = keyName (key);
			const char * ptr = strchr (name, '/');
			if (!ptr)
			{
				return keyNew ("/", KEY_CASCADING_NAME, KEY_END);
			}
			else
			{
				ssize_t length = keyGetNameSize (key);
				if ((ptr - name) == (length - 1))
				{
					return keyNew ("/", KEY_CASCADING_NAME, KEY_END);
				}
				else
				{
					return keyNew (ptr, KEY_CASCADING_NAME, KEY_END);
				}
			}
		}
	}
}
예제 #22
0
static int elektraResolveEnvUser (ElektraResolved * handle)
{
	const char * user = getenv ("USER");

	if (!user || !strcmp (user, ""))
	{
		return 0;
	}

	Key * canonify = keyNew ("user", KEY_END);
	keyAddName (canonify, user);
	size_t homeSize = sizeof (KDB_DB_HOME "/") + keyGetNameSize (canonify) + sizeof ("/" KDB_DB_USER);

	char * homeBuf = elektraMalloc (homeSize);
	strcpy (homeBuf, KDB_DB_HOME "/");
	strcat (homeBuf, keyName (canonify) + 5); // cut user/
	if (handle->relPath[0] != '/')
	{
		strcat (homeBuf, "/" KDB_DB_USER);
	}
	keyDel (canonify);
	handle->dirname = homeBuf;
	return 1;
}
예제 #23
0
int keyIsBelow (const Key * key, const Key * check)
{
	const char * keyname = 0;
	const char * checkname = 0;
	const char * ukeyname = 0;
	const char * ucheckname = 0;
	ssize_t keysize = 0;
	ssize_t checksize = 0;
	ssize_t ukeysize = 0;
	ssize_t uchecksize = 0;

	if (!key || !check) return -1;

	keyname = keyName (key);
	checkname = keyName (check);
	ukeyname = keyUnescapedName (key);
	ucheckname = keyUnescapedName (check);
	keysize = keyGetNameSize (key);
	checksize = keyGetNameSize (check);
	ukeysize = keyGetUnescapedNameSize (key);
	uchecksize = keyGetUnescapedNameSize (check);
	if (!strcmp (checkname, "/")) return 0;
	if (!strcmp (keyname, "/"))
	{
		if (checkname[0] == '/') return 1;
		if (strchr (checkname, '/')) return 1;
	}
	else if (checkname[0] == '/')
	{
		if (keyname[0] == '/')
		{
			if (!strncmp (keyname, checkname, keysize - 1))
			{
				if (ucheckname[ukeysize - 1] == '\0' && uchecksize > ukeysize)
				{
					return 1;
				}
			}
		}
		else
		{
			size_t size = 0;
			char * ptr = (char *)keyname;
			ptr = keyNameGetOneLevel (ptr, &size);
			if (size == (size_t)keysize)
			{
				return 1;
			}
			keyname += size;
			keysize = elektraStrLen (keyname);
			ptr = strrchr (ukeyname, '\0');
			ukeysize -= (ptr - ukeyname);
			if (!strncmp (keyname, checkname, keysize - 1))
			{
				if (ucheckname[ukeysize - 1] == '\0' && uchecksize > ukeysize)
				{
					return 1;
				}
			}
		}
	}
	else if (keyname[0] == '/')
	{
		size_t size = 0;
		char * ptr = (char *)checkname;
		ptr = keyNameGetOneLevel (ptr, &size);
		if (size == (size_t)checksize)
		{
			return 0;
		}
		checkname += size;
		checksize = elektraStrLen (checkname);
		ptr = strrchr (ucheckname, '\0');
		uchecksize -= (ptr - ucheckname);
		ucheckname = ptr;
		if (!strncmp (keyname, checkname, keysize - 1))
		{
			if (ucheckname[ukeysize - 1] == '\0' && uchecksize > ukeysize)
			{
				return 1;
			}
		}
	}
	else if (!strncmp (keyname, checkname, keysize - 1))
	{
		if ((ucheckname[ukeysize - 1] == '\0') && (uchecksize > ukeysize)) return 1;
	}
	return 0;
}
예제 #24
0
static CondResult evalCondition (const Key * curKey, const char * leftSide, Comparator cmpOp, const char * rightSide,
				 const char * condition, const Key * suffixList, KeySet * ks, Key * parentKey)
{
	char * lookupName = NULL;
	char * compareTo = NULL;
	Key * key;
	int len;
	long result = 0;
	if (rightSide)
	{
		if (rightSide[0] == '\'')
		{
			// right side of the statement is a literal enclosed by ''
			char * endPos = strchr (rightSide + 1, '\'');
			if (!endPos)
			{
				result = ERROR;
				goto Cleanup;
			}
			if (elektraRealloc ((void **) &compareTo, endPos - rightSide) < 0)
			{
				ELEKTRA_SET_ERROR (87, parentKey, "Out of memory");
				result = ERROR;
				goto Cleanup;
			}
			memset (compareTo, 0, endPos - rightSide);
			strncat (compareTo, rightSide + 1, endPos - rightSide - 1);
		}
		else if (rightSide && elektraStrLen (rightSide) > 1)
		{
			// not a literal, it has to be a key
			if (rightSide[0] == '@')
				len = keyGetNameSize (parentKey) + elektraStrLen (rightSide);
			else if (!strncmp (rightSide, "..", 2) || (rightSide[0] == '.'))
				len = keyGetNameSize (curKey) + elektraStrLen (rightSide);
			else
				len = elektraStrLen (rightSide);

			if (elektraRealloc ((void **) &lookupName, len) < 0)
			{
				ELEKTRA_SET_ERROR (87, parentKey, "Out of memory");
				result = ERROR;
				goto Cleanup;
			}
			if (rightSide[0] == '@')
				snprintf (lookupName, len, "%s/%s", keyName (parentKey), rightSide + 1);
			else if (rightSide[0] == '.') // either starts with . or .., doesn't matter at this point
				snprintf (lookupName, len, "%s/%s", keyName (curKey), rightSide);
			else
				snprintf (lookupName, len, "%s", rightSide);

			key = ksLookupByName (ks, lookupName, 0);
			if (!key)
			{
				if (!keyGetMeta (parentKey, "error"))
				{
					ELEKTRA_SET_ERRORF (133, parentKey, "Key %s not found but is required for the evaluation of %s",
							    lookupName, condition);
				}
				result = FALSE;
				goto Cleanup;
			}
			if (elektraRealloc ((void **) &compareTo, keyGetValueSize (key)) < 0)
			{
				ELEKTRA_SET_ERROR (87, parentKey, "Out of memory");
				result = ERROR;
				goto Cleanup;
			}
			strcpy (compareTo, keyString (key));
		}
	}
	if (leftSide[0] == '@')
		len = keyGetNameSize (parentKey) + elektraStrLen (leftSide);
	else if (!strncmp (leftSide, "..", 2) || (leftSide[0] == '.'))
		len = keyGetNameSize (curKey) + elektraStrLen (leftSide);
	else
		len = elektraStrLen (leftSide);

	if (elektraRealloc ((void **) &lookupName, len) < 0)
	{
		ELEKTRA_SET_ERROR (87, parentKey, "Out of memory");
		result = ERROR;
		goto Cleanup;
	}
	if (leftSide[0] == '@')
		snprintf (lookupName, len, "%s/%s", keyName (parentKey), leftSide + 1);
	else if (leftSide[0] == '.') // either . or .., doesn't matter here
		snprintf (lookupName, len, "%s/%s", keyName (curKey), leftSide);
	else
		snprintf (lookupName, len, "%s", leftSide);
	key = ksLookupByName (ks, lookupName, 0);
	if (cmpOp == NEX)
	{
		if (key)
			result = FALSE;
		else
			result = TRUE;
		goto Cleanup;
	}
	if (!key && cmpOp != OR && cmpOp != AND)
	{
		if (!keyGetMeta (parentKey, "error"))
		{
			ELEKTRA_SET_ERRORF (133, parentKey, "Key %s not found but is required for the evaluation of %s", lookupName,
					    condition);
		}
		result = FALSE;
		goto Cleanup;
	}
	long ret;
	if (cmpOp == OR || cmpOp == AND)
		ret = compareStrings (leftSide, rightSide, NULL);
	else
		ret = compareStrings (keyString (key), compareTo, suffixList);
	switch (cmpOp)
	{
	case EQU:
		if (!ret) result = TRUE;
		break;
	case NOT:
		if (ret) result = TRUE;
		break;
	case LT:
		if (ret < 0) result = TRUE;
		break;
	case LE:
		if (ret <= 0) result = TRUE;
		break;
	case GT:
		if (ret > 0) result = TRUE;
		break;
	case GE:
		if (ret >= 0) result = TRUE;
		break;
	case SET:
		keySetString (key, compareTo);
		result = TRUE;
		break;
	case AND:
		if (ret == 0 && !strcmp (leftSide, "'1'")) result = TRUE;
		break;
	case OR:
		if (!strcmp (leftSide, "'1'") || (rightSide && !strcmp (rightSide, "'1'"))) result = TRUE;
		break;
	default:
		result = ERROR;
		break;
	}
// freeing allocated heap
Cleanup:
	if (lookupName) elektraFree (lookupName);
	if (compareTo) elektraFree (compareTo);
	return result;
}
예제 #25
0
파일: stream.c 프로젝트: tryge/libelektra
/**
 * 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;
}
예제 #26
0
static int evalCondition(const char *leftSide, Comparator cmpOp, const char *rightSide, KeySet *ks, Key *parentKey)
{
	char *lookupName = NULL;
	char *compareTo = NULL;
	Key *key;
	int len;
	long result = 0;
	if(rightSide[0] == '\'')
	{
		char *endPos = strchr(rightSide+1, '\'');
		if(!endPos)
		{
			result = -1;
			goto Cleanup;
		}
		if(elektraRealloc((void **)&compareTo, endPos-rightSide) < 0)
		{
			ELEKTRA_SET_ERROR(87, parentKey, "Out of memory");
			result = -1;
			goto Cleanup;
		}
		memset(compareTo, 0, endPos-rightSide);
		strncat(compareTo, rightSide+1, endPos-rightSide-1);
	}
	else if(rightSide && elektraStrLen(rightSide) > 1)
	{
		len = keyGetNameSize(parentKey)+elektraStrLen(rightSide);
		if(elektraRealloc((void **)&lookupName, len) < 0)
		{
			ELEKTRA_SET_ERROR(87, parentKey, "Out of memory");
			result = -1;
			goto Cleanup;
		}
		snprintf(lookupName, len, "%s/%s", keyName(parentKey), rightSide);
		key = ksLookupByName(ks, lookupName, 0);
		if(!key)
		{
			ELEKTRA_SET_ERRORF(133, parentKey, "Key %s doesn't exist", lookupName);
			result = -1;
			goto Cleanup;
		}
		if(elektraRealloc((void **)&compareTo, keyGetValueSize(key)) < 0)
		{
			ELEKTRA_SET_ERROR(87, parentKey, "Out of memory");
			result = -1;
			goto Cleanup;
		}
		strcpy(compareTo, keyString(key));
	}

	len = keyGetNameSize(parentKey)+elektraStrLen(leftSide);
	if(elektraRealloc((void **)&lookupName, len) < 0)
	{
		ELEKTRA_SET_ERROR(87, parentKey, "Out of memory");
		result = -1;
		goto Cleanup;
	}
	snprintf(lookupName, len, "%s/%s", keyName(parentKey), leftSide);
	key = ksLookupByName(ks, lookupName, 0);
	if(!key)
	{
		ELEKTRA_SET_ERRORF(133, parentKey, "Key %s doesn't exist", lookupName);
		result = -1;
		goto Cleanup;
	}
	long ret;
	ret = compareStrings(keyString(key), compareTo);
	switch(cmpOp)
	{
		case EQU:
			if(!ret)
				result = 1;
			break;
		case NOT:
			if(ret)
				result = 1;
			break;
		case LT:
			if(ret < 0)
				result = 1;
			break;
		case LE:
			if(ret <= 0)
				result = 1;
			break;
		case GT:
			if(ret > 0)
				result = 1;
			break;
		case GE:
			if(ret >= 0)
				result = 1;
			break;
		case SET:
			keySetString(key, compareTo);
			result = 1;
			break;
		default:
			result = -1;
			break;
	}
//freeing allocated heap
Cleanup:
	if(lookupName)
		elektraFree(lookupName);
	if(compareTo)
		elektraFree(compareTo);
	return result;
}
예제 #27
0
/**
 * @internal
 *
 * Calculates the common parent to all keys in @p ks.
 *
 * This is a c-helper function, you need not implement it in bindings.
 *
 * Given the @p ks KeySet, calculates the parent name for all the keys.
 * So if @p ks contains this keys:
 *
 * @code
 *   system/sw/xorg/Monitors/Monitor1/vrefresh
 *   system/sw/xorg/Monitors/Monitor1/hrefresh
 *   system/sw/xorg/Devices/Device1/driver
 *   system/sw/xorg/Devices/Device1/mode
 * @endcode
 *
 * The common parent is @p system/sw/xorg .
 *
 * On the other hand, if we have this KeySet:
 *
 * @code
 *   system/some/thing
 *   system/other/thing
 *   user/unique/thing
 * @endcode
 *
 * No common parent is possible, so @p returnedCommonParent will contain nothing.
 *
 * @param working the Keyset to work with
 * @param returnedCommonParent a pre-allocated buffer that will receive the
 *        common parent, if found
 * @param maxSize size of the pre-allocated @p returnedCommonParent buffer
 * @return size in bytes of the parent name, or 0 if there is no common parent,
 *         or -1 to indicate an error, then @p errno must be checked.
 */
ssize_t ksGetCommonParentName (const KeySet * working, char * returnedCommonParent, size_t maxSize)
{
	size_t parentSize = 0;
	Key * current = 0;
	cursor_t cinit;
	KeySet * ks;
	ssize_t sMaxSize;

	if (maxSize > SSIZE_MAX) return -1;
	sMaxSize = maxSize;

	cinit = ksGetCursor (working);
	ks = (KeySet *)working;

	if (ksGetSize (ks) < 1) return 0;

	ksRewind (ks);
	current = ksNext (ks);
	if (keyGetNameSize (current) > sMaxSize)
	{
		/*errno=KDB_ERR_TRUNC;*/
		returnedCommonParent[0] = 0;
		return -1;
	}

	strcpy (returnedCommonParent, keyName (current));
	parentSize = elektraStrLen (returnedCommonParent);

	while (*returnedCommonParent)
	{
		ksRewind (ks);
		while ((current = ksNext (ks)) != 0)
		{
			/* Test if a key doesn't match */
			if (memcmp (returnedCommonParent, keyName (current), parentSize - 1)) break;
		}
		if (current)
		{
			/* some key failed to be a child */
			/* parent will be the parent of current parent... */
			char * delim = 0;

			// TODO: does not honor escaped characters
			if ((delim = strrchr (returnedCommonParent, KDB_PATH_SEPARATOR)))
			{
				*delim = 0;
				parentSize = elektraStrLen (returnedCommonParent);
			}
			else
			{
				*returnedCommonParent = 0;
				parentSize = 0;
				break; /* Better don't make comparison with parentSize-1 now */
			}
		}
		else
		{
			/* All keys matched (current==0) */
			/* We have our common parent to return in commonParent */
			ksSetCursor (ks, cinit);
			return parentSize;
		}
	}
	ksSetCursor (ks, cinit);
	return parentSize; /* if reached, will be zero */
}