Esempio n. 1
0
void kdbGetByName(KDB *kdb, KeySet *conf, Key *parentKey, char *where)
{
	keySetName(parentKey, "system");
	keyAddName(parentKey, where);
	kdbGet(kdb, conf, parentKey);

	keySetName(parentKey, "user");
	keyAddName(parentKey, where);
	kdbGet(kdb, conf, parentKey);
}
Esempio n. 2
0
/**
 * @internal
 * Add plugin at placement to list plugin configuration and apply it.
 *
 * @param  list      List plugin
 * @param  plugin    Plugin to add
 * @param  placement Placement name
 * @retval 0 on error
 * @retval 0 on success
 */
static int listAddPlugin (Plugin * list, Plugin * plugin, char * placement)
{
	ELEKTRA_NOT_NULL (list);
	ELEKTRA_NOT_NULL (plugin);
	ELEKTRA_NOT_NULL (placement);

	KeySet * newConfig = ksDup (list->config);

	// Find name for next item in plugins array
	Key * configBase = keyNew ("user/plugins", KEY_END);
	KeySet * array = elektraArrayGet (configBase, newConfig);
	Key * pluginItem = elektraArrayGetNextKey (array);
	ELEKTRA_NOT_NULL (pluginItem);
	keySetString (pluginItem, plugin->name);
	keyDel (configBase);

	// Create key with plugin handle
	Key * pluginHandle = keyDup (pluginItem);
	keyAddName (pluginHandle, "handle");
	keySetBinary (pluginHandle, &plugin, sizeof (plugin));

	// Create key with plugin placement
	char * placementType = placementToListPositionType (placement);
	if (placementType == NULL)
	{
		keyDel (configBase);
		keyDel (pluginItem);
		keyDel (pluginHandle);
		return 0;
	}
	Key * pluginPlacements = keyDup (pluginItem);
	keyAddName (pluginPlacements, "placements/");
	keyAddName (pluginPlacements, placementType);
	keySetString (pluginPlacements, placement);

	// Append keys to list plugin configuration
	ksAppendKey (newConfig, pluginItem);
	ksAppendKey (newConfig, pluginHandle);
	ksAppendKey (newConfig, pluginPlacements);

	ksDel (array);
	ksDel (list->config);

	// Apply new configuration
	list->config = newConfig;
	list->kdbOpen (list, NULL);

	return 1;
}
Esempio n. 3
0
/**
 * @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;
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
/**
 @retval 0 if ksCurrent does not hold an array entry
 @retval 1 if the array entry will be used because its the first
 @retval 2 if a new array entry was created
 @retval -1 error in snprintf
 */
static int elektraYajlIncrementArrayEntry (KeySet * ks)
{
	Key * current = ksCurrent (ks);
	const char * baseName = keyBaseName (current);

	if (baseName && *baseName == '#')
	{
		current = keyNew (keyName (current), KEY_END);
		if (!strcmp (baseName, "###empty_array"))
		{
			// get rid of previous key
			keyDel (ksLookup (ks, current, KDB_O_POP));
			// we have a new array entry
			keySetBaseName (current, 0);
			keyAddName (current, "#0");
			ksAppendKey (ks, current);
			return 1;
		}
		else
		{
			// we are in an array
			elektraArrayIncName (current);
			ksAppendKey (ks, current);
			return 2;
		}
	}
	else
	{
		// previous entry indicates this is not an array
		return 0;
	}
}
Esempio n. 6
0
static KeySet * prepareGlobalKS (KeySet * ks, Key * parentKey)
{
	ksRewind (ks);
	Key * cutKey = keyNew ("/", KEY_CASCADING_NAME, KEY_END);
	keyAddName (cutKey, strchr (keyName (parentKey), '/'));
	KeySet * cutKS = ksCut (ks, cutKey);
	Key * specCutKey = keyNew ("spec", KEY_END);
	KeySet * specCut = ksCut (cutKS, specCutKey);
	ksRewind (specCut);
	Key * cur;
	while ((cur = ksNext (specCut)) != NULL)
	{
		if (keyGetNamespace (cur) == KEY_NS_CASCADING)
		{
			ksAppendKey (cutKS, cur);
			keyDel (ksLookup (specCut, cur, KDB_O_POP));
		}
	}
	ksAppend (ks, specCut);
	ksDel (specCut);
	keyDel (specCutKey);
	keyDel (cutKey);
	ksRewind (cutKS);
	return cutKS;
}
Esempio n. 7
0
KeySet * elektraMetaArrayToKS (Key * key, const char * metaName)
{
	const Key * meta = keyGetMeta (key, metaName);
	if (!meta) return NULL;

	KeySet * result = ksNew (0, KS_END);

	if (keyString (meta)[0] != '#')
	{
		ksAppendKey (result, (Key *)meta);
		ksRewind (result);
		return result;
	}
	ksAppendKey (result, keyDup (meta));
	Key * currentKey = keyDup (meta);
	keyAddName (currentKey, "#");
	elektraArrayIncName (currentKey);
	Key * curMeta = NULL;
	while ((curMeta = (Key *)keyGetMeta (key, keyName (currentKey))) != NULL)
	{
		ksAppendKey (result, keyDup (curMeta));
		elektraArrayIncName (currentKey);
	}
	keyDel (currentKey);
	ksRewind (result);
	return result;
}
Esempio n. 8
0
/**
 * @internal
 * Create a new key with a different root or common name.
 *
 * Does not modify `key`. The new key needs to be freed after usage.
 *
 * Preconditions: The key name starts with `source`.
 *
 * Example:
 * ```
 * Key * source = keyNew("user/plugins/foo/placements/get", KEY_END);
 * Key * dest = renameKey ("user/plugins/foo", "user/plugins/bar", source);
 * succeed_if_same_string (keyName(dest), "user/plugins/bar/placements/get");
 * ```
 *
 *
 * @param  source Part of the key name to replace
 * @param  dest   Replaces `source`
 * @param  key    key
 * @return        key with new name
 */
static Key * renameKey (const char * source, const char * dest, Key * key)
{
	const char * name = keyName (key);
	char * baseKeyNames = strndup (name + strlen (source), strlen (name));

	Key * moved = keyDup (key);
	keySetName (moved, dest);
	keyAddName (moved, baseKeyNames);

	elektraFree (baseKeyNames);

	return moved;
}
void test_checkfile ()
{
	printf ("Check file\n");

	KeySet * modules = ksNew (0, KS_END);
	elektraModulesInit (modules, 0);
	Plugin * plugin = elektraPluginOpen ("resolver", modules, set_pluginconf (), 0);
	exit_if_fail (plugin, "did not find a resolver");

	Key * root = keyNew ("system/elektra/modules", KEY_END);
	keyAddBaseName (root, plugin->name);

	KeySet * contract = ksNew (5, KS_END);

	plugin->kdbGet (plugin, contract, root);
	keyAddName (root, "/exports/checkfile");
	Key * found = ksLookup (contract, root, 0);
	exit_if_fail (found, "did not find checkfile symbol");

	typedef int (*func_t) (const char *);
	union {
		func_t f;
		void * v;
	} conversation;

	succeed_if (keyGetBinary (found, &conversation.v, sizeof (conversation)) == sizeof (conversation), "could not get binary");
	func_t checkFile = conversation.f;


	succeed_if (checkFile ("valid") == 1, "valid file not recognised");
	succeed_if (checkFile ("/valid") == 0, "valid absolute file not recognised");
	succeed_if (checkFile ("/absolute/valid") == 0, "valid absolute file not recognised");
	succeed_if (checkFile ("../valid") == -1, "invalid file not recognised");
	succeed_if (checkFile ("valid/..") == -1, "invalid file not recognised");
	succeed_if (checkFile ("/../valid") == -1, "invalid absolute file not recognised");
	succeed_if (checkFile ("/valid/..") == -1, "invalid absolute file not recognised");
	succeed_if (checkFile ("very..strict") == -1, "resolver is currently very strict");
	succeed_if (checkFile ("very/..strict") == -1, "resolver is currently very strict");
	succeed_if (checkFile ("very../strict") == -1, "resolver is currently very strict");
	succeed_if (checkFile ("very/../strict") == -1, "resolver is currently very strict");
	succeed_if (checkFile ("/") == -1, "invalid absolute file not recognised");
	succeed_if (checkFile (".") == -1, "invalid file not recognised");
	succeed_if (checkFile ("..") == -1, "invalid file not recognised");

	ksDel (contract);
	keyDel (root);

	elektraPluginClose (plugin, 0);
	elektraModulesClose (modules, 0);
	ksDel (modules);
}
Esempio n. 10
0
ssize_t elektraKeySetName(Key *key, const char *newName,
		option_t options)
{
	if (!key) return -1;
	if (test_bit(key->flags,  KEY_FLAG_RO_NAME)) return -1;

	elektraRemoveKeyName(key);
	if (!(options & KEY_META_NAME)) keySetOwner (key, NULL);

	switch (keyGetNameNamespace(newName))
	{
	case KEY_NS_NONE: ELEKTRA_ASSERT(0);
	case KEY_NS_EMPTY:
		elektraFinalizeEmptyName(key);
		return 0; // as documented
	case KEY_NS_CASCADING: key->keyUSize=1;key->keySize=sizeof("/"); break;
	case KEY_NS_SPEC: key->keyUSize=key->keySize=sizeof("spec"); break;
	case KEY_NS_PROC: key->keyUSize=key->keySize=sizeof("proc"); break;
	case KEY_NS_DIR: key->keyUSize=key->keySize=sizeof("dir"); break;
	case KEY_NS_USER: elektraHandleUserName(key, newName); break;
	case KEY_NS_SYSTEM: key->keyUSize=key->keySize=sizeof("system"); break;
	case KEY_NS_META:
		if (!(options & KEY_META_NAME)) return -1;
		keyNameGetOneLevel(newName,&key->keySize);
		key->keyUSize = ++ key->keySize; // for null
		break;
	} // Note that we abused keyUSize for cascading and user:owner

	const size_t length = elektraStrLen(newName);
	key->key=elektraMalloc(key->keySize*2);
	memcpy(key->key, newName, key->keySize);
	if (length == key->keyUSize || length == key->keySize)
	{	// use || because full length is keyUSize in user, but keySize for /
		// newName consisted of root only
		elektraFinalizeName(key);
		return key->keyUSize;
	}

	if (elektraOnlySlashes(newName+key->keyUSize-1))
	{
		elektraFinalizeName(key);
		return key->keySize;
	}

	key->key[key->keySize-1] = '\0';
	const ssize_t ret = keyAddName(key, newName+key->keyUSize);
	if (ret == -1) elektraRemoveKeyName(key);
	else return key->keySize;
	return ret;
}
Esempio n. 11
0
static void setSectionNumber(Key *parentKey, Key *key, KeySet *ks)
{
	if (!strcmp(keyBaseName(key), INTERNAL_ROOT_SECTION))
	{
		Key *tmpKey = keyDup(key);
		keySetMeta(tmpKey, "ini/section", "0");
		keySetMeta(key, "ini/section", "0");
		keySetString(tmpKey, 0);
		ksAppendKey(ks, tmpKey);
		keyDel(tmpKey);
		return;
	}

	Key *lookupKey = keyDup(key);
	Key *lastKey = keyDup(lookupKey);

	while (1)
	{
		if (!strcmp(keyName(lookupKey), keyName(parentKey)))
		{
			if (keyGetMeta(parentKey, "ini/lastSection"))
			{
				long previousSection = atol(keyString(keyGetMeta(parentKey, "ini/lastSection")));
				++previousSection;
				char buffer[21]; //20 digits (long) + \0
				snprintf(buffer, sizeof (buffer), "%ld", previousSection);
				keySetMeta(parentKey, "ini/lastSection", buffer);
				keySetMeta(key, "ini/section", buffer);
			}
			else
			{
				keySetMeta(parentKey, "ini/lastSection", "1");
				keySetMeta(parentKey, "ini/section", "0");
				keySetMeta(key, "ini/section", "1");
			}
			keySetMeta(lastKey, "ini/section", keyString(keyGetMeta(key, "ini/section")));
			ksAppendKey(ks, lastKey);
			break;
		}
		if (keyGetMeta(ksLookup(ks, lookupKey, KDB_O_NONE), "ini/section"))
		{
			keySetMeta(key, "ini/section", keyString(keyGetMeta(ksLookup(ks, lookupKey, KDB_O_NONE), "ini/section")));
			break;
		}
		keySetName(lastKey, keyName(lookupKey));
		keyAddName(lookupKey, "..");
	}
	keyDel(lookupKey);
	keyDel(lastKey);
}
Esempio n. 12
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);
}
Esempio n. 13
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);
}
Esempio n. 14
0
static int elektraYajlParseStartArray (void * ctx)
{
	KeySet * ks = (KeySet *)ctx;
	elektraYajlIncrementArrayEntry (ks);

	Key * currentKey = ksCurrent (ks);

	Key * newKey = keyNew (keyName (currentKey), KEY_END);
	// add a pseudo element for empty array
	keyAddName (newKey, "###empty_array");
	ksAppendKey (ks, newKey);

#ifdef ELEKTRA_YAJL_VERBOSE
	printf ("elektraYajlParseStartArray with new key %s\n", keyName (newKey));
#endif

	return 1;
}
Esempio n. 15
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);
				}
			}
		}
	}
}
Esempio n. 16
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;
}
Esempio n. 17
0
static const char * isAssign (Key * key, char * expr, Key * parentKey, KeySet * ks)
{
	char * firstPtr = expr + 1;
	char * lastPtr = expr + elektraStrLen (expr) - 3;
	while (isspace (*firstPtr))
		++firstPtr;
	while (isspace (*lastPtr))
		--lastPtr;
	if (*firstPtr != '\'' || *lastPtr != '\'')
	{
		if (lastPtr <= firstPtr)
		{
			ELEKTRA_SET_ERRORF (134, parentKey,
					    "Invalid syntax: \"%s\". Check kdb info conditionals for additional information", expr);
			return NULL;
		}
		*(lastPtr + 1) = '\0';
		Key * lookupKey;
		if (*firstPtr == '@')
		{
			lookupKey = keyDup (parentKey);
			++firstPtr;
			keyAddName (lookupKey, firstPtr);
		}
		else if (!strncmp (firstPtr, "..", 2) || !strncmp (firstPtr, ".", 1))
		{
			lookupKey = keyDup (key);
			keyAddName (lookupKey, firstPtr);
		}
		else
		{
			lookupKey = keyNew (firstPtr, KEY_END);
		}
		Key * assign = ksLookup (ks, lookupKey, KDB_O_NONE);
		if (!assign)
		{
			ELEKTRA_SET_ERRORF (133, parentKey, "Key %s not found", keyName (lookupKey));
			keyDel (lookupKey);
			return NULL;
		}
		else
		{
			keyDel (lookupKey);
			return keyString (assign);
		}
	}
	else
	{
		if (firstPtr == lastPtr) // only one quote in the assign string, invalid syntax
		{
			ELEKTRA_SET_ERRORF (134, parentKey,
					    "Invalid syntax: \"%s\". Check kdb info conditionals for additional information", expr);
			return NULL;
		}
		char * nextMark = strchr (firstPtr + 1, '\'');
		if (nextMark != lastPtr) // more than two quotes, invalid syntax too
		{
			ELEKTRA_SET_ERRORF (134, parentKey,
					    "Invalid syntax: \"%s\". Check kdb info conditionals for additional information", expr);
			return NULL;
		}
		*lastPtr = '\0';
		*firstPtr = '\0';
		++firstPtr;
		return firstPtr;
	}
}
Esempio n. 18
0
/*
 * 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;
}
Esempio n. 19
0
int elektraSimpleiniGet (Plugin * handle, KeySet * returned, Key * parentKey)
{
	/* get all keys */

	if (!strcmp (keyName (parentKey), "system/elektra/modules/simpleini"))
	{
		KeySet * moduleConfig = ksNew (
			30, keyNew ("system/elektra/modules/simpleini", KEY_VALUE, "simpleini plugin waits for your orders", KEY_END),
			keyNew ("system/elektra/modules/simpleini/exports", KEY_END),
			keyNew ("system/elektra/modules/simpleini/exports/get", KEY_FUNC, elektraSimpleiniGet, KEY_END),
			keyNew ("system/elektra/modules/simpleini/exports/set", KEY_FUNC, elektraSimpleiniSet, KEY_END),
#include "readme_simpleini.c"
			keyNew ("system/elektra/modules/simpleini/infos/version", KEY_VALUE, PLUGINVERSION, KEY_END),
			keyNew ("system/elektra/modules/simpleini/config/needs", KEY_VALUE, "the needed configuration to work in a backend",
				KEY_END),
			keyNew ("system/elektra/modules/simpleini/config/needs/chars", KEY_VALUE, "Characters needed", KEY_END),
			// space in value now works:
			// TODO: characters present in format should be escaped
			/*
			keyNew ("system/elektra/modules/simpleini/config/needs/chars/20", KEY_VALUE, "61", KEY_END), // space -> a
			keyNew ("system/elektra/modules/simpleini/config/needs/chars/23", KEY_VALUE, "62", KEY_END), // # -> b
			keyNew ("system/elektra/modules/simpleini/config/needs/chars/25", KEY_VALUE, "63",
				KEY_END), // % -> c (escape character)
			keyNew ("system/elektra/modules/simpleini/config/needs/chars/3B", KEY_VALUE, "64", KEY_END), // ; -> d
			keyNew ("system/elektra/modules/simpleini/config/needs/chars/3D", KEY_VALUE, "65", KEY_END), // = -> e
			keyNew ("system/elektra/modules/simpleini/config/needs/chars/5C", KEY_VALUE, "66", KEY_END), // \\ -> f
			*/
			keyNew ("system/elektra/modules/simpleini/config/needs/chars/0A", KEY_VALUE, "67", KEY_END), // enter (NL) -> g
			keyNew ("system/elektra/modules/simpleini/config/needs/chars/0D", KEY_VALUE, "68", KEY_END), // CR -> h
			keyNew ("system/elektra/modules/simpleini/config/needs/escape", KEY_VALUE, "25", KEY_END), KS_END);
		ksAppend (returned, moduleConfig);
		ksDel (moduleConfig);
		return 1;
	}

	char * key = 0;
	char * value = 0;
	int errnosave = errno;
	FILE * fp = fopen (keyString (parentKey), "r");
	if (!fp)
	{
		ELEKTRA_SET_ERROR_GET (parentKey);
		errno = errnosave;
		return -1;
	}

	char * format = getFormat (handle, "%ms", "%m[^\n]");

	ELEKTRA_LOG ("Read from '%s' with format '%s'", keyString (parentKey), format);

	int n = 0;
	size_t size = 0;
	ssize_t ksize = 0;
#pragma GCC diagnostic ignored "-Wformat"
	// icc warning #269: invalid format string conversion
	while ((n = fscanf (fp, format, &key, &value)) >= 0)
	{
		ELEKTRA_LOG_DEBUG ("Read %d parts: '%s' with value '%s'", n, key, value);
		if (n == 0)
		{
			// discard line
			getline (&key, &size, fp);
			ELEKTRA_LOG_DEBUG ("Discard '%s'", key);
			elektraFree (key);
			key = 0;
			continue;
		}

		Key * read = keyNew (keyName (parentKey), KEY_END);

		if (keyAddName (read, key) == -1)
		{
			ELEKTRA_ADD_WARNING (ELEKTRA_WARNING_INVALID_KEY, parentKey, key);
			keyDel (read);
			continue;
		}

		if (n == 2)
		{
			keySetString (read, value);
			elektraFree (value);
			value = 0;
		}

		if (ksAppendKey (returned, read) != ksize + 1)
		{
			ELEKTRA_SET_ERROR (ELEKTRA_ERROR_NOEOF, parentKey, "duplicated key");
			return -1;
		}
		++ksize;
		elektraFree (key);
		key = 0;
	}

	if (feof (fp) == 0)
	{
		elektraFree (format);
		fclose (fp);
		ELEKTRA_SET_ERROR (ELEKTRA_ERROR_NOEOF, parentKey, "not at the end of file");
		return -1;
	}

	elektraFree (format);
	fclose (fp);

	return 1; /* success */
}
Esempio n. 20
0
static int iniKeyToElektraKey (void *vhandle, const char *section, const char *name, const char *value, unsigned short lineContinuation)
{
	CallbackHandle *handle = (CallbackHandle *)vhandle;
	Key *appendKey = keyDup (handle->parentKey);
	keySetMeta(appendKey, "ini/lastSection", 0);
	if (!section || *section == '\0')
	{
		section = INTERNAL_ROOT_SECTION;
	}
	appendKey = createUnescapedKey(appendKey, section);
	short mergeSections = 0;
	Key *existingKey = NULL;
	if ((existingKey = ksLookup(handle->result, appendKey, KDB_O_NONE)))
	{
		if (keyGetMeta(existingKey, "ini/duplicate"))
		{
			mergeSections = 1;
		}
	}
	setSectionNumber(handle->parentKey, appendKey, handle->result);
	appendKey = createUnescapedKey(appendKey, name);
	existingKey = ksLookup(handle->result, appendKey, KDB_O_NONE);

	if (existingKey)
	{
		//a key with the same name already exists
		if (handle->array)
		{
			//array support is turned on 
			keySetMeta(appendKey, "ini/section", 0);
			if (keyGetMeta(existingKey, "ini/array"))
			{
				//array already exists, appending new key
				const char *lastIndex = keyString(keyGetMeta(existingKey, "ini/array"));
				keyAddBaseName(appendKey, lastIndex);
				keySetMeta(appendKey, "order/parent", 0);
				keySetMeta(appendKey, "ini/array", 0);
				keySetMeta(appendKey, "order", 0);
				if (elektraArrayIncName(appendKey) == 1)
				{
					return -1;
				}
				keySetString(appendKey, value);
				keySetMeta(appendKey, "ini/key", 0);
				ksAppendKey(handle->result, appendKey);
				keySetMeta(existingKey, "ini/array", keyBaseName(appendKey));
				ksAppendKey(handle->result, existingKey);
			}
			else
			{
				//creating a new array
				Key *sectionKey = keyDup(appendKey);
				keyAddName(sectionKey, "..");
				char *origVal = strdup(keyString(existingKey));
				keySetString(appendKey, "");
				keySetMeta(appendKey, "ini/array", "#1");
				keySetMeta(appendKey, "order/parent", keyName(sectionKey));
				setSectionNumber(handle->parentKey, appendKey, handle->result);
				setOrderNumber(handle->parentKey, appendKey);
				keySetMeta(appendKey, "ini/key", "");
				ksAppendKey(handle->result, keyDup(appendKey));
				keySetMeta(appendKey, "ini/key", 0);
				keySetMeta(appendKey, "ini/array", 0);
				keySetMeta(appendKey, "parent", 0);
				keyAddName(appendKey, "#");
				keySetMeta(appendKey, "order", 0);
				if (elektraArrayIncName(appendKey) == -1)
				{
					free(origVal);
					return -1;
				}
				keySetString(appendKey, origVal);
				ksAppendKey(handle->result, keyDup(appendKey));
				free(origVal);
				if (elektraArrayIncName(appendKey) == -1)
				{
					return -1;
				}
				keySetMeta(appendKey, "parent", 0);
				keySetString(appendKey, value);
				ksAppendKey(handle->result, keyDup(appendKey));
				keyDel(appendKey);
				keyDel(sectionKey);
			}
			return 1;
		}
		else if(!lineContinuation)
		{
			ELEKTRA_SET_ERRORF(141, handle->parentKey, "Key: %s\n", name);
			return -1;
		}
	}

	setSectionNumber(handle->parentKey, appendKey, handle->result);
	if (value == NULL)
		keySetMeta(appendKey, "ini/empty", "");
	if (!lineContinuation)
	{
		flushCollectedComment (handle, appendKey);
		keySetString (appendKey, value);
		keySetMeta(appendKey, "ini/key", "");
		ksAppendKey (handle->result, appendKey);
		if (mergeSections)
		{
			keySetMeta(appendKey, "order", 0);
			insertNewKeyIntoExistendOrder(appendKey, handle->result);
		}
		else
		{
			setOrderNumber(handle->parentKey, appendKey);
		}
	}
	else
	{
		existingKey = ksLookup (handle->result, appendKey, KDB_O_NONE);
		keyDel (appendKey);
		/* something went wrong before because this key should exist */
		if (!existingKey) return -1;

		elektraKeyAppendLine(existingKey, value);
	}


	return 1;
}
Esempio n. 21
0
static int csvRead(KeySet *returned, Key *parentKey, char delim, short useHeader, unsigned long fixColumnCount, const char **colNames)
{
    const char *fileName;
    fileName = keyString(parentKey);
    FILE *fp = NULL;
    fp = fopen(fileName, "rb");
    if(!fp)
    {
        ELEKTRA_SET_ERRORF(116, parentKey, "couldn't open file %s\n", fileName);
        return -1;
    }

    unsigned long length = 0;
    length = getLineLength(fp);
    if(length == 0)
    {
        ELEKTRA_ADD_WARNING(118, parentKey, "Empty file");
        fclose(fp);
        return -2;
    }

    char *lineBuffer;
    lineBuffer = elektraMalloc((length * sizeof(char))+1);
    if(!lineBuffer)
    {
        ELEKTRA_SET_ERROR(87, parentKey, "Out of memory");
        return -1;
    }
    if(!fgets(lineBuffer, length, fp))
    {
        ELEKTRA_SET_ERROR(116, parentKey, "Cant read from file");
        return -1;
    }

    unsigned long columns = 0;
    columns = getColumnCount(lineBuffer, delim);
    if(fixColumnCount)
    {
        if(columns != fixColumnCount)
        {
            ELEKTRA_SET_ERROR(117, parentKey, "illegal number of columns in Header line");
            elektraFree(lineBuffer);
            fclose(fp);
            return -1;
        }
    }
    unsigned long colCounter = 0;
    unsigned long lineCounter = 0;
    unsigned long offset = 0;
    char *col;
    char buf[INTSTR_MAX];
    int nr_keys = 1;
    KeySet *header = ksNew(0, KS_END);
    Key *key;

    if(useHeader == 1)
    {
        colCounter = 0;
        offset = 0;
        while((col = parseLine(lineBuffer, delim, offset, parentKey, lineCounter)) != NULL)
        {
            offset += elektraStrLen(col);
            key = keyDup(parentKey);
            if(colNames && (colNames+colCounter))
            {
                keyAddBaseName(key, colNames[colCounter]);
            }
            else
            {
                keyAddBaseName(key, col);
            }
            keySetMeta(key, "csv/order", itostr(buf, colCounter, sizeof(buf)-1));
            ksAppendKey(header, key);
            ++colCounter;
        }
        fseek(fp, 0, SEEK_SET);
    }
    else
    {
        colCounter = 0;
        //if no headerline exists name the columns 0..N where N is the number of columns
        key = keyDup(parentKey);
        keyAddName(key, "#");
        while(colCounter < columns)
        {
            if(elektraArrayIncName(key) == -1)
            {
                elektraFree(lineBuffer);
                keyDel(key);
                ksDel(header);
                fclose(fp);
                return -1;
            }
            keySetMeta(key, "csv/order", itostr(buf, colCounter, sizeof(buf)-1));
            if(colNames && (colNames+colCounter))
                keySetBaseName(key, colNames[colCounter]);
            ksAppendKey(header, keyDup(key));
            ++colCounter;
        }
        keyDel(key);
        if(useHeader == 0)
            fseek(fp, 0, SEEK_SET);
    }
    Key *dirKey;
    Key *cur;
    dirKey = keyDup(parentKey);
    keyAddName(dirKey, "#");
    while(!feof(fp))
    {
        length = getLineLength(fp);
        if(length == 0)
            break;
        if(elektraRealloc((void **)&lineBuffer, (length * sizeof(char))+1) < 0)
        {
            fclose(fp);
            elektraFree(lineBuffer);
            ksDel(header);
            keyDel(dirKey);
            ELEKTRA_SET_ERROR(87, parentKey, "Out of memory");
            return -1;
        }
        fgets(lineBuffer, length, fp);
        if(elektraArrayIncName(dirKey) == -1)
        {
            elektraFree(lineBuffer);
            keyDel(dirKey);
            ksDel(header);
            fclose(fp);
            return -1;
        }
        ++nr_keys;
        offset = 0;
        colCounter = 0;
        char *lastIndex = "#0";
        while((col = parseLine(lineBuffer, delim, offset, parentKey, lineCounter)) != NULL)
        {
            cur = getKeyByOrderNr(header, colCounter);
            offset += elektraStrLen(col);
            key = keyDup(dirKey);
            keyAddBaseName(key, keyBaseName(cur));
            keySetString(key, col);
            keySetMeta(key, "csv/order", itostr(buf, colCounter, sizeof(buf)-1));
            ksAppendKey(returned, key);
            lastIndex = (char *)keyBaseName(key);
            ++nr_keys;
            ++colCounter;
        }
        keySetString(dirKey, lastIndex);
        ksAppendKey(returned, keyDup(dirKey));
        if(colCounter != columns)
        {
            if(fixColumnCount)
            {
                ELEKTRA_SET_ERRORF(117, parentKey, "illegal number of columns in line %lu", lineCounter);
                elektraFree(lineBuffer);
                fclose(fp);
                keyDel(dirKey);
                ksDel(header);
                return -1;
            }
            ELEKTRA_ADD_WARNINGF(118, parentKey, "illegal number of columns in line %lu", lineCounter);
        }
        ++lineCounter;
    }
    key = keyDup(parentKey);
    keySetString(key, keyBaseName(dirKey));
    ksAppendKey(returned, key);
    keyDel(dirKey);
    fclose(fp);
    elektraFree(lineBuffer);
    ksDel(header);
    return 1;
}
Esempio n. 22
0
/**
 * Walks through kdb->split and adds all backends below parentKey to split.
 *
 * Sets syncbits to 2 if it is a default or root backend (which needs splitting).
 * The information is copied from kdb->split.
 *
 * @pre split needs to be empty, directly after creation with elektraSplitNew().
 *
 * @pre there needs to be a valid defaultBackend
 *      but its ok not to have a trie inside KDB.
 *
 * @pre parentKey must be a valid key! (could be implemented more generally,
 *      but that would require splitting up of keysets of the same backend)
 *
 * @param split will get all backends appended
 * @param kdb the handle to get information about backends
 * @param parentKey the information below which key the backends are from interest
 * @ingroup split
 * @retval 1 always
 */
int elektraSplitBuildup (Split * split, KDB * kdb, Key * parentKey)
{
	/* For compatibility reasons invalid names are accepted, too.
	 * This solution is faster than checking the name of parentKey
	 * every time in loop.
	 * The parentKey might be null in some unit tests, so also check
	 * for this. */
	const char * name = keyName (parentKey);
	if (!parentKey || !name || !strcmp (name, "") || !strcmp (name, "/"))
	{
		parentKey = 0;
	}
	else if (name[0] == '/')
	{
		Key * key = keyNew (0, KEY_END);
		for (elektraNamespace ins = KEY_NS_FIRST; ins <= KEY_NS_LAST; ++ins)
		{
			if (!elektraKeySetNameByNamespace (key, ins)) continue;
			keyAddName (key, keyName (parentKey));
			elektraSplitBuildup (split, kdb, key);
		}
		keyDel (key);
		return 1;
	}

	/* Returns the backend the key is in or the default backend
	   otherwise */
	Backend * backend = elektraMountGetBackend (kdb, parentKey);

#if DEBUG && VERBOSE
	printf (" with parent %s\n", keyName (parentKey));
#endif
	for (size_t i = 0; i < kdb->split->size; ++i)
	{
#if DEBUG && VERBOSE
		printf ("  %zu with parent %s\n", i, keyName (kdb->split->parents[i]));
#endif
		if (!parentKey)
		{
#if DEBUG && VERBOSE
			printf ("   def add %s\n", keyName (kdb->split->parents[i]));
#endif
			/* Catch all: add all mountpoints */
			elektraSplitAppend (split, kdb->split->handles[i], keyDup (kdb->split->parents[i]), kdb->split->syncbits[i]);
		}
		else if (backend == kdb->split->handles[i] && keyRel (kdb->split->parents[i], parentKey) >= 0)
		{
#if DEBUG && VERBOSE
			printf ("   exa add %s\n", keyName (kdb->split->parents[i]));
#endif
			/* parentKey is exactly in this backend, so add it! */
			elektraSplitAppend (split, kdb->split->handles[i], keyDup (kdb->split->parents[i]), kdb->split->syncbits[i]);
		}
		else if (keyRel (parentKey, kdb->split->parents[i]) >= 0)
		{
#if DEBUG && VERBOSE
			printf ("   rel add %s\n", keyName (kdb->split->parents[i]));
#endif
			/* this backend is completely below the parentKey, so lets add it. */
			elektraSplitAppend (split, kdb->split->handles[i], keyDup (kdb->split->parents[i]), kdb->split->syncbits[i]);
		}
	}

	return 1;
}