コード例 #1
0
ファイル: spec.c プロジェクト: sanssecours/libelektra
static int handleInvalidConflict (Key * parentKey, Key * key, OnConflict onConflict)
{
	int ret = 0;
	switch (onConflict)
	{
	case ERROR:
		ELEKTRA_SET_ERRORF (142, parentKey, "Invalid key %s\n", keyName (key));
		ret = -1;
		break;
	case WARNING:
		ELEKTRA_ADD_WARNINGF (143, parentKey, "Invalid key %s\n", keyName (key));
		break;
	case INFO:
	{
		const char * infoString = "Invalid key ";
		const size_t len = elektraStrLen (infoString) + elektraStrLen (keyName (key)) - 1;
		char * buffer = elektraMalloc (len);
		snprintf (buffer, len, "Invalid key %s\n", keyName (key));
		elektraMetaArrayAdd (key, "logs/spec/info", buffer);
		elektraFree (buffer);
	}
	break;
	case IGNORE:

		break;
	}
	return ret;
}
コード例 #2
0
static void test_keyGetBaseName (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");

	const char * constBaseName = "a";
	size_t constBaseNameSize = elektraStrLen (constBaseName);
	ssize_t baseNameSize = keyGetFullNameSize (found);
	char * baseName = elektraMalloc (baseNameSize);
	ssize_t ret = keyGetBaseName (found, baseName, baseNameSize);
	if (ret < 1)
	{
		yield_error ("Key base name NULL or size error");
	}
	else
	{
		succeed_if ((size_t) ret == elektraStrLen (constBaseName), "Key base name has wrong size");
	}

	succeed_if (elektraStrNCmp (constBaseName, baseName, constBaseNameSize) == 0, "Key base name is wrong");

	elektraFree (baseName);
	keyDel (parentKey);
	ksDel (ks);
	closeStoragePlugin (storagePlugin);
}
コード例 #3
0
ファイル: spec.c プロジェクト: sanssecours/libelektra
static int handleMissingConflict (Key * parentKey, Key * key, Key * conflictMeta, OnConflict onConflict)
{
	int ret = 0;
	const char * problemKeys = elektraMetaArrayToString (key, keyName (conflictMeta), ", ");
	switch (onConflict)
	{
	case ERROR:
		ELEKTRA_SET_ERRORF (142, parentKey, "%s has missing subkeys: %s\n", keyName (key), problemKeys);
		ret = -1;
		break;
	case WARNING:
		ELEKTRA_ADD_WARNINGF (143, parentKey, "%s has missing subkeys: %s\n", keyName (key), problemKeys);
		break;
	case INFO:
	{
		const char * infoString = "has missing subkeys:";
		const size_t len = elektraStrLen (infoString) + elektraStrLen (problemKeys) + elektraStrLen (keyName (key));
		char * buffer = elektraMalloc (len);
		snprintf (buffer, len, "%s %s %s", keyName (key), infoString, problemKeys);
		elektraMetaArrayAdd (key, "logs/spec/info", buffer);
		elektraFree (buffer);
	}
	break;
	case IGNORE:

		break;
	}
	if (problemKeys)
	{
		elektraFree ((void *) problemKeys);
	}
	return ret;
}
コード例 #4
0
static int elektraResolvePasswdHome (resolverHandle * p, Key * warningsKey)
{
	ssize_t bufSize = sysconf (_SC_GETPW_R_SIZE_MAX);
	if (bufSize == -1) bufSize = 16384; // man 3 getpwuid

	char * buf = elektraMalloc (bufSize);
	if (!buf) return -1;
	struct passwd pwd;
	struct passwd * result;
	int s;

	s = getpwuid_r (getuid (), &pwd, buf, bufSize, &result);
	if (result == NULL)
	{
		elektraFree (buf);
		if (s != 0)
		{
			ELEKTRA_ADD_WARNING (90, warningsKey, strerror (s));
		}
		return -1;
	}

	const char * home = pwd.pw_dir;
	size_t filenameSize = elektraStrLen (home) + elektraStrLen (p->path) - 1;

	p->filename = elektraMalloc (filenameSize);
	snprintf (p->filename, filenameSize, "%s/%s", home, (p->path) + 2);

	elektraFree (buf);
	return 0;
}
コード例 #5
0
ファイル: spec.c プロジェクト: sanssecours/libelektra
static int handleOutOfRangeConflict (Key * parentKey, Key * key, Key * specKey, Key * conflictMeta, OnConflict onConflict)
{
	int ret = 0;
	switch (onConflict)
	{
	case ERROR:
		ELEKTRA_SET_ERRORF (142, parentKey, "%s has invalid number of members: %s. Expected: %s\n", keyName (key),
				    keyString (conflictMeta), keyString (keyGetMeta (specKey, "array")));
		ret = -1;
		break;
	case WARNING:
		ELEKTRA_ADD_WARNINGF (143, parentKey, "%s has invalid number of members: %s. Expected: %s\n", keyName (key),
				      keyString (conflictMeta), keyString (keyGetMeta (specKey, "array")));
		break;
	case INFO:
	{
		const char * infoString = "%s has invalid number of member: %s. Expected: %s";
		const size_t len = elektraStrLen (infoString) + elektraStrLen (keyName (key)) + MAX_CHARS_IN_LONG +
				   keyGetValueSize (keyGetMeta (specKey, "array")) - 2;
		char * buffer = elektraMalloc (len);
		snprintf (buffer, len, infoString, keyName (key), keyString (conflictMeta), keyString (keyGetMeta (specKey, "array")));
		elektraMetaArrayAdd (key, "logs/spec/info", buffer);
		elektraFree (buffer);
	}
	break;
	case IGNORE:

		break;
	}
	return ret;
}
コード例 #6
0
ファイル: filename.c プロジェクト: 0003088/libelektra
static void elektraResolveSystemXDGHelper (char ** filename, const char * path, const char * result)
{
	size_t configDirSize = elektraStrLen (result);
	size_t pathSize = elektraStrLen (path);
	size_t filenameSize = configDirSize + pathSize + sizeof ("/") + 1;

	elektraRealloc ((void **) filename, filenameSize);
	strcpy (*filename, result);
	strcat (*filename, "/");
	strcat (*filename, path);
}
コード例 #7
0
static void elektraResolveSystemXDGHelper (resolverHandle * p, const char * result)
{
	size_t configDirSize = elektraStrLen (result);
	size_t pathSize = elektraStrLen (p->path);
	size_t filenameSize = configDirSize + pathSize + sizeof ("/") + 1;

	elektraRealloc ((void *)&p->filename, filenameSize);
	strcpy (p->filename, result);
	strcat (p->filename, "/");
	strcat (p->filename, p->path);
}
コード例 #8
0
ファイル: filename.c プロジェクト: 0003088/libelektra
static int elektraResolveSystemPasswd (ElektraResolved * handle, Key * warningsKey)
{
	char * dir = elektraResolvePasswd (warningsKey);
	if (!dir) return -1;
	size_t filenameSize = elektraStrLen (dir) + elektraStrLen (handle->relPath) - 1;
	char * resolved = elektraMalloc (filenameSize);
	snprintf (resolved, filenameSize, "%s/%s", dir, handle->relPath + 2);
	elektraFree (dir);
	handle->fullPath = resolved;
	return 0;
}
コード例 #9
0
ファイル: filename.c プロジェクト: 0003088/libelektra
static void elektraResolveFinishByDirname (ElektraResolved * handle, ElektraResolveTempfile tmpDir)
{
	size_t filenameSize = elektraStrLen (handle->relPath) + elektraStrLen (handle->dirname);
	char * filename = elektraMalloc (filenameSize);
	strcpy (filename, handle->dirname);
	if (handle->relPath[0] != '/')
	{
		strcat (filename, "/");
	}
	strcat (filename, handle->relPath);
	elektraFree (handle->dirname);
	handle->fullPath = filename;
	elektraResolveFinishByFilename (handle, tmpDir);
}
コード例 #10
0
static void test_keyGetString (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 ();
	const char * name = "user/tests/storage/specialkey";
	const char * value = "special value";
	size_t realValueSize = elektraStrLen (value);
	Key * key = keyNew (name, KEY_VALUE, value, KEY_END);
	ksAppendKey (ks, key);
	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, name, 0);
	succeed_if (found, "did not find key");

	ssize_t apiValueSize = keyGetValueSize (found);
	char * apiString = elektraMalloc (apiValueSize);
	succeed_if (keyGetString (found, apiString, apiValueSize) == (ssize_t) realValueSize, "Key string has wrong size");

	succeed_if (elektraStrNCmp (value, apiString, realValueSize) == 0, "Key string value is wrong");

	elektraFree (apiString);
	keyDel (parentKey);
	ksDel (ks);
	closeStoragePlugin (storagePlugin);
}
コード例 #11
0
ファイル: ini.c プロジェクト: tryge/libelektra
static void setSubOrderNumber(Key *key, const char *oldOrder)
{
	char *lastIndexPtr = NULL;
	char *newOrder = elektraMalloc(elektraStrLen(oldOrder)+ELEKTRA_MAX_ARRAY_SIZE);
	if ((lastIndexPtr = strrchr(oldOrder, '/')))
	{
		kdb_long_long_t subIndex = 0;
		char *ptr = lastIndexPtr;
		++ptr; //skip /
		++ptr; //skip #
		while (*ptr == '_')
		{
			++ptr;
		}
		elektraReadArrayNumber(ptr, &subIndex);
		++subIndex;
		int len = (lastIndexPtr+1) - oldOrder;
		char buffer[ELEKTRA_MAX_ARRAY_SIZE];
		elektraWriteArrayNumber(buffer, subIndex);
		sprintf(newOrder, "%.*s%s", len, oldOrder, buffer);
	}
	else
	{
		sprintf(newOrder, "%s/#1", oldOrder);
	}
	keySetMeta(key, "order", newOrder);
	elektraFree(newOrder);
}
コード例 #12
0
static char *parseLine(char *origLine, char delim, unsigned long offset, Key *parentKey, unsigned long lineNr)
{
    char *line = (origLine + offset);
    if(*line == '\0')
        return NULL;
    char *ptr = strchr(line, delim);

    if(ptr == NULL)
    {
        ssize_t len = elektraStrLen(line);
        if(line[len-2] == '\n')
        {
            line[len-2] = '\0';
        }
        else if(line[len-1] == '\0')
        {
            ELEKTRA_ADD_WARNINGF(136, parentKey, "Unexpected end of line(%lu) , expected \\n, got \\0 \n %s\n", lineNr, origLine);
        }
        else if(line[len-2] == '\r')
        {
            ELEKTRA_ADD_WARNINGF(136, parentKey, "Unexpected end of line(%lu) , expected \\n, found \\r \n %s\n", lineNr, origLine);
            line[len-2] = '\0';
        }
        else
        {
            ELEKTRA_ADD_WARNINGF(136, parentKey, "Unexpected end of line(%lu) , expected \\n, but got 0x%x \n %s\n", lineNr, line[len-2], origLine);

        }
    }
    else
    {
        *ptr = '\0';
    }
    return line;
}
コード例 #13
0
ファイル: meta.c プロジェクト: reox/libelektra
char * elektraMetaArrayToString (Key * key, const char * metaName, const char * delim)
{
	char * result = NULL;
	Key * lookupElem = keyDup (keyGetMeta (key, metaName));
	keyAddBaseName (lookupElem, "#0");
	Key * elem = (Key *)keyGetMeta (key, keyName (lookupElem));
	if (elem != NULL)
	{
		elektraRealloc ((void **)&result, keyGetValueSize (elem));
		snprintf (result, keyGetValueSize (elem), "%s", keyString (elem));
	}
	elektraArrayIncName (lookupElem);
	elem = (Key *)keyGetMeta (key, keyName (lookupElem));
	while (elem != NULL)
	{
		elektraRealloc ((void **)&result,
				elektraStrLen (result) + keyGetValueSize (elem) + 1); // String (incl. +2 times \0) + delimiter + whitespace
		strcat (result, delim);
		strcat (result, keyString (elem));
		elektraArrayIncName (lookupElem);
		elem = (Key *)keyGetMeta (key, keyName (lookupElem));
	}
	keyDel (lookupElem);
	return result;
}
コード例 #14
0
ファイル: proposal.c プロジェクト: BernhardDenner/libelektra
/**
 * @brief Set a formatted string
 *
 * @param key the key to set the string value
 * @param format NULL-terminated text format string
 * @param ... more arguments
 *
 * @return the size of the string as set (with including 0)
 */
ssize_t keySetStringF (Key * key, const char * format, ...)
{
	va_list arg_list;

	keySetMeta (key, "binary", 0);

	va_start (arg_list, format);
	char * p = elektraVFormat (format, arg_list);
	va_end (arg_list);

	if (!p)
	{
		return -1;
	}

	if (key->data.c)
	{
		elektraFree (key->data.c);
	}

	key->data.c = p;
	key->dataSize = elektraStrLen (key->data.c);
	set_bit (key->flags, KEY_FLAG_SYNC);

	return key->dataSize;
}
コード例 #15
0
ファイル: filename.c プロジェクト: 0003088/libelektra
static int elektraResolveSystemBuildin (ElektraResolved * handle, ElektraResolveTempfile tmpDir, Key * warningsKey)
{
	size_t filenameSize = sizeof (KDB_DB_SYSTEM) + elektraStrLen (handle->relPath) + sizeof ("/");
	char * resolved = NULL;
	if (KDB_DB_SYSTEM[0] == '~')
	{
		char * resolvedPath = elektraMalloc (filenameSize);
		strcpy (resolvedPath, KDB_DB_SYSTEM);
		strcat (resolvedPath, "/");
		strcat (resolvedPath, handle->relPath);
		char * oldPath = handle->relPath;
		handle->relPath = resolvedPath;
		elektraResolveSystemPasswd (handle, warningsKey);
		elektraFree (resolvedPath);
		handle->relPath = oldPath;
	}
	else
	{
		resolved = elektraMalloc (filenameSize);
		strcpy (resolved, KDB_DB_SYSTEM);
		strcat (resolved, "/");
		strcat (resolved, handle->relPath);
		handle->fullPath = resolved;
	}
	elektraResolveFinishByFilename (handle, tmpDir);
	return 1;
}
コード例 #16
0
ファイル: spec.c プロジェクト: sanssecours/libelektra
// elektra wildcard syntax to fnmatch syntax
static char * keyNameToMatchingString (const Key * key)
{
	uint8_t arrayCount = 0;
	char * name = strchr (keyName (key), '/');
	if (!name) return elektraStrDup (keyName (key));
	for (char * ptr = name; *ptr != '\0'; ++ptr)
		if (*ptr == '#') ++arrayCount;
	char * pattern = elektraMalloc (elektraStrLen (name) + arrayCount);
	char * dst = pattern;
	for (char * src = (name + 1); *src != '\0'; ++src)
	{
		if (*src == '_' && *(src - 1) == '/' && (*(src + 1) == '/' || *(src + 1) == '\0'))
		{
			*dst++ = '*';
		}
		else if (*src == '#' && *(src - 1) == '/' && (*(src + 1) == '/' || *(src + 1) == '\0'))
		{
			*dst++ = '#';
			*dst++ = '*';
		}
		else
		{
			*dst++ = *src;
		}
	}
	*dst = '\0';
	return pattern;
}
コード例 #17
0
ファイル: keyname.c プロジェクト: fberlakovich/libelektra
/**
 * @brief Add an already escaped name to the keyname.
 *
 * The same way as in keySetName() this method finds the canonical pathname:
 * - it will ignore /./
 * - it will remove a level when /../ is used
 * - it will remove multiple slashes ////
 *
 * For example:
 * @snippet keyName.c add name
 *
 * Unlike keySetName() it adds relative to the previous name and
 * cannot change the namespace of a key.
 * For example:
 * @snippet keyName.c namespace
 *
 * The passed name needs to be valid according the @link keyname key name rules @endlink.
 * It is not allowed to:
 * - be empty
 * - end with unequal number of \\
 *
 * @param key the key where a name should be added
 * @param newName the new name to append
 *
 * @since 0.8.11
 *
 * @retval size of the new key
 * @retval -1 if key is a null pointer or did not have a valid name before
 * @retval -1 if newName is not a valid escaped name
 * @retval -1 on allocation errors
 * @retval -1 if key was inserted to a keyset before
 * @retval 0 if nothing was done because newName had only slashes, is too short, is empty or is null
 * @ingroup keyname
 */
ssize_t keyAddName (Key * key, const char * newName)
{
	if (!key) return -1;
	if (test_bit (key->flags, KEY_FLAG_RO_NAME)) return -1;
	if (!key->key) return -1;
	if (!strcmp (key->key, "")) return -1;
	if (!newName) return 0;
	size_t const nameSize = elektraStrLen (newName);
	if (nameSize < 2) return 0;
	if (!elektraValidateKeyName (newName, nameSize)) return -1;

	const size_t origSize = key->keySize;
	const size_t newSize = origSize + nameSize;
	elektraRealloc ((void **)&key->key, newSize * 2);
	if (!key->key) return -1;

	size_t size = 0;
	const char * p = newName;
	int avoidSlash = 0;

	if (*key->key == '/') avoidSlash = key->keySize == 2;

	--key->keySize; // loop assumes that key->key[key->keySize] is last character and not NULL

	/* iterate over each single folder name removing repeated '/', .  and .. */
	while (*(p = keyNameGetOneLevel (p + size, &size)))
	{
		if (size == 1 && strncmp (p, ".", 1) == 0)
		{
			continue; /* just ignore current directory */
		}
		else if (size == 2 && strncmp (p, "..", 2) == 0) /* give away one level*/
		{
			elektraRemoveOneLevel (key, &avoidSlash);
			continue;
		}

		if (!avoidSlash)
		{
			/* Add a '/' to the end of key name */
			key->key[key->keySize] = KDB_PATH_SEPARATOR;
			key->keySize++;
		}
		else
		{
			avoidSlash = 0;
		}

		/* carefully append basenames */
		char * d = key->key + key->keySize;
		memcpy (d, p, size);
		key->keySize += size;
	}

	++key->keySize; /*for \\0 ending*/

	elektraFinalizeName (key);

	return origSize == key->keySize ? 0 : key->keySize;
}
コード例 #18
0
ファイル: keyname.c プロジェクト: fberlakovich/libelektra
/**
 * Calculates number of bytes needed to store basename of @p key.
 *
 * Key names that have only root names (e.g. @c "system" or @c "user"
 * or @c "user:domain" ) does not have basenames, thus the function will
 * return 1 bytes to store "".
 *
 * Basenames are denoted as:
 * - @c system/some/thing/basename -> @c basename
 * - @c user:domain/some/thing/base\\/name > @c base\\/name
 *
 * @param key the key object to work with
 * @return size in bytes of @p key's basename including ending NULL
 * @see keyBaseName(), keyGetBaseName()
 * @see keyName(), keyGetName(), keySetName()
 * @ingroup keyname
 */
ssize_t keyGetBaseNameSize (const Key * key)
{
	const char * baseName = keyBaseName (key);
	if (!baseName) return -1;

	return elektraStrLen (baseName);
}
コード例 #19
0
ファイル: dpkg.c プロジェクト: BernhardDenner/libelektra
static void appendToKey (Key * key, const char * line)
{
	char * buffer;
	size_t len = keyGetValueSize (key) + elektraStrLen (line) - 1;
	buffer = elektraMalloc (len);
	snprintf (buffer, len, "%s%s", keyString (key), line);
	keySetString (key, buffer);
	elektraFree (buffer);
}
コード例 #20
0
/**
 * @internal
 * Setup ZeroMq for receiving notifications.
 *
 * @param data plugin data containing context, socket, etc.
 */
void elektraZeroMqRecvSetup (ElektraZeroMqRecvPluginData * data)
{
	// create zmq context
	if (!data->zmqContext)
	{
		data->zmqContext = zmq_ctx_new ();
		if (data->zmqContext == NULL)
		{
			ELEKTRA_LOG_WARNING ("zmq_ctx_new failed %s", zmq_strerror (zmq_errno ()));
			return;
		}
	}

	// create publish socket
	if (!data->zmqSubscriber)
	{
		data->zmqSubscriber = zmq_socket (data->zmqContext, ZMQ_SUB);
		if (data->zmqSubscriber == NULL)
		{
			ELEKTRA_LOG_WARNING ("zmq_socket failed %s", zmq_strerror (zmq_errno ()));
			zmq_close (data->zmqSubscriber);
			return;
		}

		// subscribe to notifications
		char * keyCommitType = "Commit";
		if (zmq_setsockopt (data->zmqSubscriber, ZMQ_SUBSCRIBE, keyCommitType, elektraStrLen (keyCommitType)) != 0)
		{
			ELEKTRA_LOG_WARNING ("failed to subscribe to %s messages", keyCommitType);
		}

		// connect to endpoint
		int result = zmq_connect (data->zmqSubscriber, data->endpoint);
		if (result != 0)
		{
			ELEKTRA_LOG_WARNING ("zmq_connect error: %s\n", zmq_strerror (zmq_errno ()));
			zmq_close (data->zmqSubscriber);
			data->zmqSubscriber = NULL;
			return;
		}
	}

	if (!data->zmqAdapter)
	{
		// attach ZeroMq adater and wait for socket to be writable
		data->zmqAdapter = elektraIoAdapterZeroMqAttach (data->zmqSubscriber, data->ioBinding, ELEKTRA_IO_ADAPTER_ZEROMQCB_READ,
								 zeroMqRecvSocketReadable, data);
		if (!data->zmqAdapter)
		{
			ELEKTRA_LOG_WARNING ("could not attach zmq adapter");
			zmq_close (data->zmqSubscriber);
			data->zmqSubscriber = NULL;
			return;
		}
	}
}
コード例 #21
0
ファイル: keyname.c プロジェクト: tryge/libelektra
/**
 * Sets @c baseName as the new basename for @c key.
 *
 * Only the baseName will be affected and no other part of the key.
 *
 * All text after the last @c '/' in the @p key keyname is erased and
 * @p baseName is appended.
 *
 * So let us suppose @p key has name @c "system/dir1/dir2/key1". If @p baseName
 * is @c "key2", the resulting key name will be @c "system/dir1/dir2/key2".
 * If @p baseName is empty or NULL, the resulting key name will
 * be @c "system/dir1/dir2".
 *
 * This function does proper escaping on the supplied name argument.
 *
 * You can use all names to set as basename (e.g. . (dot), ..
 * (dot-dot), % and "" (empty)). They will be properly escaped.
 *
 * A simple example is:
 * @snippet basename.c set base basic
 *
 * If you want to add and not change the basename, use keyAddBaseName()
 * instead. If you do not want escaping, use keyAddName() instead.
 *
 * To add an inactive key name, use:
 * @snippet testabi_key.c base1
 *
 * When you want to add an array item, use:
 * @snippet testabi_key.c base2
 *
 * @see keyname for more details on special names
 *
 * @param key the key object to work with
 * @param baseName the string used to overwrite the basename of the key
 * @return the size in bytes of the new key name
 * @retval -1 on NULL pointers
 * @retval -1 if key was inserted to a keyset before
 * @see keyAddBaseName()
 * @see keySetName() to set a new name
 * @ingroup keyname
 */
ssize_t keySetBaseName(Key *key, const char *baseName)
{
	if (!key) return -1;
	if (test_bit(key->flags,  KEY_FLAG_RO_NAME)) return -1;
	if (!key->key) return -1;

	size_t size=0;
	char *searchBaseName=0;
	size_t searchBaseSize=0;
	char *p = key->key;

	while (*(p=keyNameGetOneLevel(p+size,&size)))
	{
		searchBaseName=p;
		searchBaseSize=size+1;
	}

	if (!searchBaseName || searchBaseName==key->key)
	{
		return -1;
	}

	// truncate the key
	key->keySize -= searchBaseSize;

	if (!baseName)
	{
		// just remove base name, so we are finished
		elektraFinalizeName(key);
		return key->keySize;
	}

	char *escaped = elektraMalloc (strlen (baseName) * 2 + 2);
	elektraEscapeKeyNamePart(baseName, escaped);
	size_t sizeEscaped = elektraStrLen (escaped);

	elektraRealloc((void**)&key->key, (key->keySize+sizeEscaped)*2);
	if (!key->key)
	{
		elektraFree (escaped);
		return -1;
	}

	key->key [key->keySize - 1] = KDB_PATH_SEPARATOR;
	memcpy (key->key + key->keySize,
			escaped, sizeEscaped);

	elektraFree (escaped);

	key->keySize += sizeEscaped;
	elektraFinalizeName(key);

	return key->keySize;
}
コード例 #22
0
ファイル: keyvalue.c プロジェクト: tryge/libelektra
/**
 * Set the value for @p key as @p newStringValue.
 *
 * The function will allocate and save a private copy of @p newStringValue, so
 * the parameter can be freed after the call.
 *
 * String values will be saved in backend storage, when kdbSetKey() will be
 * called, in UTF-8 universal encoding, regardless of the program's current
 * encoding, when iconv plugin is present.
 *
 * @note The type will be set to KEY_TYPE_STRING.
 * When the type of the key is already a string type it won't be changed.
 *
 * @param key the key to set the string value
 * @param newStringValue NULL-terminated text string to be set as @p key's
 * 	value
 * @return the number of bytes actually saved in private struct including final
 * 	NULL
 * @retval 1 if newStringValue is a NULL pointer, this will make the
 *           string empty (string only containing null termination)
 * @retval -1 if key is a NULL pointer
 * @see keyGetString(), keyValue(), keyString()
 * @ingroup keyvalue
 */
ssize_t keySetString(Key *key, const char *newStringValue)
{
    ssize_t ret=0;

    if (!key) return -1;

    keySetMeta (key, "binary", 0);

    if (!newStringValue || newStringValue[0] == '\0') ret=keySetRaw(key,0,0);
    else ret=keySetRaw(key,newStringValue,elektraStrLen(newStringValue));

    return ret;
}
コード例 #23
0
ファイル: internal.c プロジェクト: 0003088/libelektra
/**Copy string into new allocated memory.
 *
 * You need to free the memory yourself.
 *
 * @note that size is determined at runtime.
 *       So if you have a size information, don't use
 *       that function.
 *
 * @param s the null-terminated string to duplicate
 *
 * @ingroup internal
 * @return 0 if out of memory, a pointer otherwise
 * @pre s must be a c-string.
 * @see elektraFree
 * @see elektraStrLen
 * @see elektraStrNDup
 */
char * elektraStrDup (const char * s)
{
	void * tmp = 0;
	size_t l = 0;
	ELEKTRA_ASSERT (s, "Tried to duplicate null pointer");

	l = elektraStrLen (s);
	ELEKTRA_ASSERT (l, "Size of string to duplicate is zero");
	tmp = elektraMalloc (l);
	if (tmp) memcpy (tmp, s, l);

	return tmp;
}
コード例 #24
0
ファイル: keyname.c プロジェクト: tryge/libelektra
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;
}
コード例 #25
0
ファイル: hosts.c プロジェクト: intfrr/libelektra
/** Appends a comment to key found in line.
 *
 * Comments are marked with number signs, also called pound sign (#).
 *
 * White spaces are space and tab.
 * Lines can not start with blank or tab.
 * Blank lines are allowed and preserved in oomments
 * Trailing white spaces are allowed.
 * Only one host entry per line is allowed.
 *
 *
 *
 * @param line Will be closed with \0 where the comment begins
 * @return 0 when the caller should go on
 * @return 1 when the caller should continue (with next iteration)
 */
int elektraHostsAppendComment (char *comment, char *line)
{
	size_t i;
	size_t s = elektraStrLen(line);
	size_t c = elektraStrLen(comment);
	char *endline;

	if (line[0] == '\n')
	{
		strncat (comment, "\n", HOSTS_KDB_BUFFER_SIZE-c-1);
		return 1; /* Empty line, so go on.. */
	}

	if (line[0] == '#')
	{
		strncat (comment, line+1, HOSTS_KDB_BUFFER_SIZE-c-2);
		return 1; /* Complete line is comment, so go on.. */
	}


	for (i=0; i<s; i++)
	{
		if (line [i] == '#') /* comment found */
		{
			/* Remove the endline, might be not there
			 * if size limit of fgets hit or at end of file */
			endline = strrchr (line, '\n');
			if (endline) *endline = '\0';

			/* Copy the comment */
			strncat (comment, line+i+1, HOSTS_KDB_BUFFER_SIZE-c-s-2);
			line[i] = '\0';
			return 0; /* There should be a key here */
		}
	}
	return 0; /* No # found */
}
コード例 #26
0
ファイル: test_internal.c プロジェクト: KurtMi/libelektra
static void test_elektraStrLen (void)
{
	char charSeq[5];

	printf ("Test elektraStrLen\n");
	for (int i = 1; i < 255; ++i)
	{
		charSeq[0] = '\33';
		charSeq[1] = 'a';
		charSeq[2] = i;       // 1..254
		charSeq[3] = 256 - i; // 255..2
		charSeq[4] = '\0';

		// printf ("%s %d %d\n", charSeq, elektraStrLen (charSeq), strlen(charSeq));
		succeed_if (elektraStrLen ((char *)charSeq) == 5, "could not deduce correct multichar sequence length");
	}
}
コード例 #27
0
/**
 * Create subscriber socket for tests.
 * @internal
 *
 * @param  subscribeFilter filter for subscriptions
 * @return                 new socket
 */
static void * createTestSocket (char * subscribeFilter)
{
	// leave the system some time before binding again
	usleep (TIME_HOLDOFF);

	void * subSocket = zmq_socket (context, ZMQ_SUB);
	int result = zmq_bind (subSocket, TEST_ENDPOINT);
	if (result != 0)
	{
		yield_error ("zmq_bind failed");
		printf ("zmq error was: %s\n", zmq_strerror (zmq_errno ()));
		exit (-1);
	}
	if (subscribeFilter != NULL)
	{
		exit_if_fail (zmq_setsockopt (subSocket, ZMQ_SUBSCRIBE, subscribeFilter, elektraStrLen (subscribeFilter)) == 0,
			      "subscribe failed"); // subscribe to all messages
	}
	return subSocket;
}
コード例 #28
0
ファイル: keyname.c プロジェクト: fberlakovich/libelektra
/**
 * Bytes needed to store the key name including user domain and ending NULL.
 *
 * @param key the key object to work with
 * @return number of bytes needed to store key name including user domain
 * @retval 1 on empty name
 * @retval -1 on NULL pointer
 * @see keyGetFullName(), keyGetNameSize()
 * @ingroup keyname
 */
ssize_t keyGetFullNameSize (const Key * key)
{
	size_t returnedSize = 0;

	if (!key) return -1;

	if (!key->key) return 1;

	returnedSize = elektraStrLen (key->key);

	if (keyNameIsUser (key->key) && keyGetMeta (key, "owner")) returnedSize += keyGetOwnerSize (key);

	/*
	   After 2 elektraStrLen() calls looks like we counted one more NULL.
	   But we need this byte count because a full key name has an
	   additional ':' char.
	*/

	return returnedSize;
}
コード例 #29
0
ファイル: keytometa.c プロジェクト: 0003088/libelektra
/*
 * Appends a line to the MetaKey of the supplied Key
 * If no MetaKey with the given name exists yet, a new
 * one is created containing the supplied line. If
 * the MetaKey exists, the supplied line is added as
 * a new line to the value of the MetaKey (i.e. a newline
 * followed by the given line is appended to the metadata)
 *
 * @param	target the Key whose MetaKey is to be modified
 * @param	metaName the name of the MetaKey which is to be modified
 * @param	line the line to be appended to the matadata
 * @return	the new value size of the modified MetaKey
 * @retval 	-1 on NULL pointers or if a memory allocation error occurs
 *
 * @see keyGetValueSize(Key *key)
 *
 */
int elektraKeyAppendMetaLine (Key * target, const char * metaName, const char * line)
{
	if (!target) return 0;
	if (!metaName) return 0;
	if (!line) return 0;

	if (!keyGetMeta (target, metaName))
	{
		keySetMeta (target, metaName, line);
		return keyGetValueSize (keyGetMeta (target, metaName));
	}

	const Key * existingMeta = keyGetMeta (target, metaName);
	char * buffer = elektraMalloc (keyGetValueSize (existingMeta) + strlen (line) + 1);
	if (!buffer) return 0;

	keyGetString (existingMeta, buffer, keyGetValueSize (existingMeta));
	strcat (buffer, "\n");
	strncat (buffer, line, elektraStrLen (line));

	keySetMeta (target, metaName, buffer);
	elektraFree (buffer);
	return keyGetValueSize (keyGetMeta (target, metaName));
}
コード例 #30
0
ファイル: keytest.c プロジェクト: BernhardDenner/libelektra
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;
}