Пример #1
0
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;
}
Пример #2
0
static int elektraResolveSystemBuildin (resolverHandle * p, Key * warningsKey)
{
	size_t filenameSize = sizeof (KDB_DB_SYSTEM) + strlen (p->path) + sizeof ("/") + 1;
	if (KDB_DB_SYSTEM[0] == '~')
	{
		const char * oldPath = p->path;
		char * path = elektraMalloc (filenameSize);
		strcpy (path, KDB_DB_SYSTEM);
		strcat (path, "/");
		strcat (path, p->path);
		p->path = path;
		elektraResolvePasswdHome (p, warningsKey);
		elektraFree (path);
		p->path = oldPath;
	}
	else
	{
		p->filename = elektraMalloc (filenameSize);
		strcpy (p->filename, KDB_DB_SYSTEM);
		strcat (p->filename, "/");
		strcat (p->filename, p->path);
	}
	elektraResolveFinishByFilename (p);
	return 1;
}
Пример #3
0
static void elektraResolveSystem (resolverHandle * p, Key * errorKey)
{
	char * system = getenv ("ALLUSERSPROFILE");

	if (!system)
	{
		system = "";
		ELEKTRA_ADD_WARNING (90, errorKey, "could not get ALLUSERSPROFILE, using /");
	}
	else
	{
		escapePath (system);
	}

	if (p->path[0] == '/')
	{
		/* Use absolute path */
		size_t filenameSize = strlen (system) + strlen (p->path) + 1;
		p->filename = elektraMalloc (filenameSize);
		strcpy (p->filename, system);
		strcat (p->filename, p->path);
		return;
	}
	size_t filenameSize = sizeof (KDB_DB_SYSTEM) + strlen (system) + strlen (p->path) + sizeof ("/") + 1;
	p->filename = elektraMalloc (filenameSize);
	strcpy (p->filename, system);
	strcat (p->filename, KDB_DB_SYSTEM);
	strcat (p->filename, "/");
	strcat (p->filename, p->path);
	return;
}
Пример #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
static char * loadFile (FILE * fh)
{
	/* open the file */
	char * content = 0;

	if (fseek (fh, 0, SEEK_END) != 0) return 0;

	long fileSize = ftell (fh);
	rewind (fh);

	if (fileSize > 0)
	{
		content = elektraMalloc (fileSize * sizeof (char) + 1);
		if (content == 0) return 0;
		int readBytes = fread (content, sizeof (char), fileSize, fh);

		if (feof (fh) || ferror (fh) || readBytes != fileSize) return 0;

		/* null terminate the string, as fread doesn't do it */
		content[fileSize] = 0;
	}
	else if (fileSize == 0)
	{
		content = elektraMalloc (1);
		if (content == 0) return 0;
		*content = (char)0;
	}

	return content;
}
Пример #6
0
static void test_keyGetBinary (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";
	size_t realValueSize = 42;
	void * value = elektraMalloc (realValueSize);
	memset (value, 42, realValueSize);

	Key * key = keyNew (name, KEY_END);
	keySetBinary (key, value, realValueSize);
	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 * apiValue = elektraMalloc (apiValueSize);
	succeed_if (keyGetBinary (found, apiValue, apiValueSize) == (ssize_t) realValueSize, "Key binary has wrong size");

	succeed_if (elektraStrNCmp (value, apiValue, realValueSize) == 0, "Key binary value is wrong");

	elektraFree (apiValue);
	elektraFree (value);
	keyDel (parentKey);
	ksDel (ks);
	closeStoragePlugin (storagePlugin);
}
Пример #7
0
/**
 * Converts string to (@p direction = @c UTF8_TO) and from
 * (@p direction = @c UTF8_FROM) UTF-8.
 * 
 * Since Elektra provides portability for key names and string values between
 * different codesets, you should use this helper in your backend to convert
 * to and from universal UTF-8 strings, when storing key names, values and
 * comments.
 *
 * Broken locales in applications can cause problems too. Make sure to load
 * the environment locales in your application using
 * @code
setlocale (LC_ALL, "");
 * @endcode
 *
 * Otherwise kdbbUTF8Engine and this plugin will quit
 * with error when non-ascii characters appear.
 *
 * Binary values are not effected.
 *
 * If iconv() or nl_langinfo() is not available on your system, or if iconv()
 * this plugin can't be used.
 *
 * @param direction must be @c UTF8_TO (convert from current non-UTF-8 to
 * 	UTF-8) or @c UTF8_FROM (convert from UTF-8 to current non-UTF-8)
 * @param string before the call: the string to be converted; after the call:
 * 	reallocated to carry the converted string
 * @param inputOutputByteSize before the call: the size of the string including
 * 	leading NULL; after the call: the size of the converted string including
 * 	leading NULL
 * @retval 0 on success
 * @retval -1 on failure
 * @ingroup backendhelper
 *
 */
int kdbbUTF8Engine (Plugin * handle, int direction, char ** string, size_t * inputOutputByteSize)
{
	/* Current solution is not very complete.
	 * Iconv might well be available when a usable nl_langinfo is not.
	 * In this case we it should be possible to determine charset through other means
	 * See http://www.cl.cam.ac.uk/~mgk25/unicode.html#activate for more info on a possible solution */

	char * converted = 0;
	char *readCursor, *writeCursor;
	size_t bufferSize;
	iconv_t converter;

	if (!*inputOutputByteSize) return 0;
	if (!kdbbNeedsUTF8Conversion (handle)) return 0;

	if (direction == UTF8_TO)
		converter = iconv_open (getTo (handle), getFrom (handle));
	else
		converter = iconv_open (getFrom (handle), getTo (handle));

	if (converter == (iconv_t) (-1)) return -1;

	/* work with worst case, when all chars are wide */
	bufferSize = *inputOutputByteSize * 4;
	converted = elektraMalloc (bufferSize);
	if (!converted) return -1;

	readCursor = *string;
	writeCursor = converted;
	/* On some systems and with libiconv, arg1 is const char **.
	 * ICONV_CONST is defined by configure if the system needs this */
	if (iconv (converter, &readCursor, inputOutputByteSize, &writeCursor, &bufferSize) == (size_t) (-1))
	{
		elektraFree (converted);
		iconv_close (converter);
		return -1;
	}

	/* calculate the UTF-8 string byte size, that will be returned */
	*inputOutputByteSize = writeCursor - converted;
	/* store the current kdbbDecoded string for future free */
	readCursor = *string;
	/* allocate an optimal size area to store the converted string */
	*string = elektraMalloc (*inputOutputByteSize);
	/* copy all that matters for returning */
	memcpy (*string, converted, *inputOutputByteSize);
	/* release memory used by passed string */
	elektraFree (readCursor);
	/* release buffer memory */
	elektraFree (converted);
	/* release the conversor engine */
	iconv_close (converter);
	return 0;
}
Пример #8
0
int elektraIconvSet (Plugin * handle, KeySet * returned, Key * parentKey)
{
	Key * cur;

	if (!kdbbNeedsUTF8Conversion (handle)) return 0;

	ksRewind (returned);

	while ((cur = ksNext (returned)) != 0)
	{
		if (keyIsString (cur))
		{
			/* String or similar type of value */
			size_t convertedDataSize = keyGetValueSize (cur);
			char * convertedData = elektraMalloc (convertedDataSize);

			memcpy (convertedData, keyString (cur), keyGetValueSize (cur));
			if (kdbbUTF8Engine (handle, UTF8_TO, &convertedData, &convertedDataSize))
			{
				ELEKTRA_SET_ERRORF (46, parentKey,
						    "Could not convert string %s, got result %s,"
						    " encoding settings are from %s to %s (but swapped for write)",
						    keyString (cur), convertedData, getFrom (handle), getTo (handle));
				elektraFree (convertedData);
				return -1;
			}
			keySetString (cur, convertedData);
			elektraFree (convertedData);
		}
		const Key * meta = keyGetMeta (cur, "comment");
		if (meta)
		{
			/* String or similar type of value */
			size_t convertedDataSize = keyGetValueSize (meta);
			char * convertedData = elektraMalloc (convertedDataSize);

			memcpy (convertedData, keyString (meta), keyGetValueSize (meta));
			if (kdbbUTF8Engine (handle, UTF8_TO, &convertedData, &convertedDataSize))
			{
				ELEKTRA_SET_ERRORF (46, parentKey,
						    "Could not convert string %s, got result %s,"
						    " encodings settings are from %s to %s (but swapped for write)",
						    keyString (meta), convertedData, getFrom (handle), getTo (handle));
				elektraFree (convertedData);
				return -1;
			}
			keySetMeta (cur, "comment", convertedData);
			elektraFree (convertedData);
		}
	}

	return 1; /* success */
}
Пример #9
0
/**
 * @brief Given filename, calcualtes dirname+tempfile
 *
 * @param p resolverHandle with filename set
 */
static void elektraResolveFinishByFilename(resolverHandle *p)
{
	size_t filenameSize = strlen(p->filename);
	p->dirname = elektraMalloc (filenameSize);
	char * dup = strdup(p->filename);
	//dirname might change the buffer, so better work on a copy
	strcpy (p->dirname, dirname(dup));
	elektraFree (dup);

	p->tempfile = elektraMalloc (filenameSize + POSTFIX_SIZE);
	elektraGenTempFilename(p->tempfile, p->filename);
}
Пример #10
0
static Key * prefToKey (Key * parentKey, PrefType type, const char * pref)
{
	Key * key = keyNew (keyName (parentKey), KEY_END);
	keyAddBaseName (key, prefix[type]);
	char * localString = elektraStrDup (pref);
	char * cPtr = strstr (localString, ",");
	*cPtr = '\0';
	char * sPtr = localString;
	++sPtr;
	*sPtr++ = '\0';
	char * ePtr = cPtr - 1;
	elektraRstrip (sPtr, &ePtr);
	size_t keyLen = ePtr - sPtr;
	char * prefKey = elektraMalloc (keyLen + 1);
	snprintf (prefKey, keyLen + 1, "%s", sPtr);
	char * tPtr = strtok (prefKey, ".");
	if (tPtr) keyAddBaseName (key, tPtr);
	while ((tPtr = strtok (NULL, ".")) != NULL)
	{
		keyAddBaseName (key, tPtr);
	}
	elektraFree (prefKey);
	sPtr = cPtr + 1;
	sPtr = elektraLskip (sPtr);
	ePtr = strrchr (sPtr, ')');
	*ePtr-- = '\0';
	elektraRstrip (sPtr, &ePtr);
	size_t argLen = ePtr - sPtr + 1;
	char * prefArg = elektraMalloc (argLen + 1);
	snprintf (prefArg, argLen + 1, "%s", sPtr);
	if (!strcmp (prefArg, "true") || !(strcmp (prefArg, "false")))
	{
		keySetMeta (key, "type", "boolean");
		keySetString (key, prefArg);
	}
	else if (prefArg[0] == '"' && prefArg[strlen (prefArg) - 1] == '"')
	{
		// TODO: else if list
		keySetMeta (key, "type", "string");
		*prefArg = '\0';
		*(prefArg + (strlen (prefArg + 1))) = '\0';
		keySetString (key, (prefArg + 1));
	}
	else
	{
		keySetMeta (key, "type", "integer");
		keySetString (key, prefArg);
	}
	elektraFree (prefArg);
	elektraFree (localString);
	return key;
}
Пример #11
0
/**
 * 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
/**
 * @retval 0 if variant did not have a result
 * @retval 1 on success
 */
static int elektraResolveSystem (char variant, resolverHandle * p, Key * warningsKey)
{
	// hardcoded path wins against variants for now
	if (p->path[0] == '/')
	{
		/* Use absolute path */
		size_t filenameSize = strlen (p->path) + 1;
		p->filename = elektraMalloc (filenameSize);
		strcpy (p->filename, p->path);

		elektraResolveFinishByFilename (p);
		return 1;
	}
	if (p->path[0] == '~')
	{
		if (elektraResolvePasswdHome (p, warningsKey) == -1) return -1;
		elektraResolveFinishByFilename (p);
		return 1;
	}
	switch (variant)
	{
	case 'x':
		return elektraResolveSystemXDG (p, warningsKey);
	case 'b':
		return elektraResolveSystemBuildin (p, warningsKey);
		// TODO: also document in doc/COMPILE.md
	}
	return -1;
}
Пример #13
0
static void elektraResolveUser (resolverHandle * p, Key * warningsKey)
{
	p->filename = elektraMalloc (KDB_MAX_PATH_LENGTH);

#if defined(_WIN32)
	CHAR home[MAX_PATH];
	if (SUCCEEDED (SHGetFolderPath (NULL, CSIDL_PROFILE, NULL, 0, home)))
	{
		escapePath (home);
	}
	else
	{
		strcpy (home, "");
		ELEKTRA_ADD_WARNING (90, warningsKey, "could not get home (CSIDL_PROFILE), using /");
	}
#else
	char * home = (char *)getenv ("HOME");
	if (!home)
	{
		home = "";
		ELEKTRA_ADD_WARNING (90, warningsKey, "could not get home, using /");
	}
#endif

	strcpy (p->filename, home);
	strcat (p->filename, "/");
	strncat (p->filename, p->path, KDB_MAX_PATH_LENGTH);
}
Пример #14
0
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;
}
Пример #15
0
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;
}
Пример #16
0
static void test_elektraMalloc (void)
{
	char * buffer = 0;
	buffer = elektraMalloc (50);
	exit_if_fail (buffer, "buffer must not be 0 after allocation");
	elektraRealloc ((void **)&buffer, 100);
	exit_if_fail (buffer, "buffer must not be 0 after reallocation");
	elektraRealloc ((void **)&buffer, 20);
	exit_if_fail (buffer, "buffer must not be 0 after reallocation");
	elektraFree (buffer);

	buffer = elektraCalloc (50);
	exit_if_fail (buffer, "buffer must not be 0 after allocation");
	for (int i = 0; i < 50; ++i)
	{
		succeed_if (buffer[i] == 0, "elektraCalloc did not initialize buffer with zeros");
	}
	elektraRealloc ((void **)&buffer, 100);
	exit_if_fail (buffer, "buffer must not be 0 after reallocation");
	elektraRealloc ((void **)&buffer, 20);
	exit_if_fail (buffer, "buffer must not be 0 after reallocation");

	char * dup = elektraStrNDup (buffer, 20);
	exit_if_fail (dup, "could not duplicate buffer");
	elektraFree (buffer);
	buffer = 0;
	for (int i = 0; i < 20; ++i)
	{
		succeed_if (dup[i] == 0, "elektraStrNDup did not correctly copy zero-buffer");
	}
	elektraFree (dup);
}
Пример #17
0
/**
 * Check if supplied filename is ok.
 *
 * This symbol is exported and used during mounting.
 *
 * @retval 1 on success (Relative path)
 * @retval 0 on success (Absolute path)
 * @retval -1 on a non-valid file
 */
int ELEKTRA_PLUGIN_FUNCTION(resolver,checkFile)(const char* filename)
{
	if (!filename) return -1;
	if (filename[0] == '0') return -1;

	size_t size = strlen(filename);
	char *buffer = elektraMalloc(size + sizeof ("system/"));
	strcpy(buffer, "system/");
	strcat(buffer, filename);

	/* Because of the outbreak bugs these tests are not enough */
	Key *check = keyNew(buffer, KEY_END);
	if (!strcmp(keyName(check), "")) goto error;
	if (!strcmp(keyName(check), "system")) goto error;
	keyDel(check);
	elektraFree (buffer);

	/* Be strict, don't allow any .., even if it would be ok sometimes */
	if (strstr (filename, "..") != 0) return -1;

	if (filename[0] == '/') return 0;

	return 1;

error:
	keyDel (check);
	elektraFree (buffer);
	return -1;
}
Пример #18
0
int elektraSpecloadOpen (Plugin * handle, Key * errorKey)
{
	Specload * specload = elektraMalloc (sizeof (Specload));

	KeySet * conf = elektraPluginGetConfig (handle);
	if (ksLookupByName (conf, "system/module", 0) != NULL || ksLookupByName (conf, "system/sendspec", 0) != NULL)
	{
		elektraFree (specload);
		return ELEKTRA_PLUGIN_STATUS_SUCCESS;
	}

	if (!getAppAndArgs (conf, &specload->app, &specload->argv, errorKey))
	{
		elektraFree (specload);
		return ELEKTRA_PLUGIN_STATUS_ERROR;
	}

	specload->quickDumpConfig = ksNew (0, KS_END);
	specload->quickDump = elektraInvokeOpen ("quickdump", specload->quickDumpConfig, errorKey);

	if (!specload->quickDump)
	{
		elektraFree (specload);
		return ELEKTRA_PLUGIN_STATUS_ERROR;
	}

	elektraPluginSetData (handle, specload);

	return ELEKTRA_PLUGIN_STATUS_SUCCESS;
}
Пример #19
0
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);
}
Пример #20
0
static int iniCommentToMeta (void *vhandle, const char *comment)
{
	CallbackHandle *handle = (CallbackHandle *)vhandle;

	size_t commentSize = strlen (comment) + 1;

	if (!handle->collectedComment)
	{
		handle->collectedComment = elektraMalloc (commentSize);

		if (!handle->collectedComment) return 0;

		strncpy (handle->collectedComment, comment, commentSize);
	}
	else
	{
		size_t newCommentSize = strlen (handle->collectedComment) + commentSize + 2;
		handle->collectedComment = realloc (handle->collectedComment, newCommentSize);

		if (!handle->collectedComment) return 0;

		strcat (handle->collectedComment, "\n");
		strncat (handle->collectedComment, comment, newCommentSize);
	}

	return 1;
}
Пример #21
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;
}
Пример #22
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
}
Пример #23
0
/**
 * Creates a new KeyRegistration structure and appends it at the end of the registration list
 * @internal
 *
 * @param pluginState   internal plugin data structure
 * @param key           key
 * @param callback      callback for changes
 * @param context       context for callback
 * @param freeContext   context needs to be freed on close
 *
 * @return pointer to created KeyRegistration structure or NULL if memory allocation failed
 */
static KeyRegistration * elektraInternalnotificationAddNewRegistration (PluginState * pluginState, Key * key,
									ElektraNotificationChangeCallback callback, void * context,
									int freeContext)
{
	KeyRegistration * item = elektraMalloc (sizeof *item);
	if (item == NULL)
	{
		return NULL;
	}
	item->next = NULL;
	item->lastValue = NULL;
	item->name = elektraStrDup (keyName (key));
	item->callback = callback;
	item->context = context;
	item->sameOrBelow = 0;
	item->freeContext = freeContext;

	if (pluginState->head == NULL)
	{
		// Initialize list
		pluginState->head = pluginState->last = item;
	}
	else
	{
		// Make new item end of list
		pluginState->last->next = item;
		pluginState->last = item;
	}

	return item;
}
Пример #24
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;
}
Пример #25
0
static void validateArrayRange (Key * parent, long validCount, Key * specKey)
{
	const Key * arrayRange = keyGetMeta (specKey, "array");
	if (arrayRange != NULL)
	{
		char * rangeString = elektraMalloc (keyGetValueSize (arrayRange));
		keyGetString (arrayRange, rangeString, keyGetValueSize (arrayRange));
		char * delimPtr = strchr (rangeString, '-');
		long min = 0;
		long max = 0;
		if (delimPtr)
		{
			char * maxString = delimPtr + 1;
			*delimPtr = '\0';
			char * minString = rangeString;
			min = atoi (minString);
			max = atoi (maxString);
		}
		else
		{
			min = max = atoi (rangeString);
		}
		if (validCount < min || validCount > max)
		{
			char buffer[MAX_CHARS_IN_LONG + 1];
			snprintf (buffer, sizeof (buffer), "%ld", validCount);
			keySetMeta (parent, "conflict/range", buffer);
		}
		elektraFree (rangeString);
	}
}
Пример #26
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);
}
Пример #27
0
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;
}
Пример #28
0
static void test_keyValue (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";
	size_t valueSize = 42;
	void * value = elektraMalloc (valueSize);
	memset (value, 42, valueSize);

	Key * key = keyNew (name, KEY_END);
	keySetBinary (key, value, valueSize);
	ksAppendKey (ks, keyDup (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");
	compare_key (key, found);

	elektraFree (value);
	keyDel (parentKey);
	ksDel (ks);
	keyDel (key);
	closeStoragePlugin (storagePlugin);
}
Пример #29
0
// 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;
}
Пример #30
0
/**
 * @internal
 *
 * Set raw  data as the value of a key.
 * If NULL pointers are passed, key value is cleaned.
 * This method will not change or set the key type, and should only
 * be used internally in elektra.
 *
 * @param key the key object to work with
 * @param newBinary array of bytes to set as the value
 * @param dataSize number bytes to use from newBinary, including the final NULL
 * @return The number of bytes actually set in internal buffer.
 * @retval 1 if it was a string which was deleted
 * @retval 0 if it was a binary which was deleted
 * @see keySetType(), keySetString(), keySetBinary()
 * @ingroup keyvalue
 */
ssize_t keySetRaw(Key *key, const void *newBinary, size_t dataSize)
{
    if (!key) return -1;
    if (key->flags & KEY_FLAG_RO_VALUE) return -1;

    if (!dataSize || !newBinary)
    {
        if (key->data.v) {
            elektraFree (key->data.v);
            key->data.v=0;
        }
        key->dataSize = 0;
        set_bit(key->flags, KEY_FLAG_SYNC);
        if (keyIsBinary(key)) return 0;
        return 1;
    }

    key->dataSize=dataSize;
    if (key->data.v)
    {
        char *p=0;
        p=realloc(key->data.v,key->dataSize);
        if (0==p) return -1;
        key->data.v=p;
    } else {
        char *p=elektraMalloc(key->dataSize);
        if (0==p) return -1;
        key->data.v=p;
    }


    memcpy(key->data.v,newBinary,key->dataSize);
    set_bit(key->flags, KEY_FLAG_SYNC);
    return keyGetValueSize (key);
}