Exemple #1
0
/*
 * str_replace_home -- (internal) replace $HOME string with user home directory
 *
 * If function does not find $HOME string it will return haystack untouched.
 * Otherwise it will allocate new string with $HOME replaced with provided
 * home_dir path. haystack will be released and newly created string returned.
 */
static char *
str_replace_home(char *haystack, const char *home_dir)
{
	const size_t placeholder_len = strlen(HOME_STR_PLACEHOLDER);
	const size_t home_len = strlen(home_dir);
	size_t haystack_len = strlen(haystack);

	char *pos = strstr(haystack, HOME_STR_PLACEHOLDER);
	if (!pos)
		return haystack;

	const char *after = pos + placeholder_len;
	if (isalnum(*after))
		return haystack;

	haystack_len += home_len - placeholder_len + 1;
	char *buf = malloc(sizeof(char) * haystack_len);
	if (!buf)
		RPMEMD_FATAL("!snprintf");

	*pos = '\0';
	int r = snprintf(buf, haystack_len, "%s%s%s", haystack, home_dir,
		after);
	if (r < 0)
		RPMEMD_FATAL("!snprintf");

	free(haystack);
	return buf;
}
Exemple #2
0
/*
 * config_set_default -- (internal) load default config
 */
static void
config_set_default(struct rpmemd_config *config, const char *poolset_dir)
{
	config->log_file = strdup(RPMEMD_DEFAULT_LOG_FILE);
	if (!config->log_file)
		RPMEMD_FATAL("!strdup");

	config->poolset_dir = strdup(poolset_dir);
	if (!config->poolset_dir)
		RPMEMD_FATAL("!strdup");

	config->persist_apm	= false;
	config->persist_general	= true;
	config->use_syslog	= true;
	config->max_lanes	= RPMEM_DEFAULT_MAX_LANES;
	config->log_level	= RPD_LOG_ERR;
}
Exemple #3
0
/*
 * concat_dir_and_file_name -- (internal) concatenate directory and file name
 * into single string path
 */
static void
concat_dir_and_file_name(char *path, size_t size, const char *dir,
	const char *file)
{
	int r = snprintf(path, size, "%s/%s", dir, file);
	if (r < 0)
		RPMEMD_FATAL("!snprintf");
}
Exemple #4
0
/*
 * get_home_dir -- (internal) return user home directory
 *
 * Function will lookup user home directory in order:
 * 1. HOME environment variable
 * 2. Password file entry using real user ID
 */
static void
get_home_dir(char *str, size_t size)
{
	char *home = getenv(HOME_ENV);
	if (home) {
		int r = snprintf(str, size, "%s", home);
		if (r < 0)
			RPMEMD_FATAL("!snprintf");
	} else {
		uid_t uid = getuid();
		struct passwd *pw = getpwuid(uid);
		if (pw == NULL)
			RPMEMD_FATAL("!getpwuid");

		int r = snprintf(str, size, "%s", pw->pw_dir);
		if (r < 0)
			RPMEMD_FATAL("!snprintf");
	}
}
Exemple #5
0
/*
 * parse_config_string -- (internal) parse string value
 */
static inline char *
parse_config_string(const char *value)
{
	if (strlen(value) == 0) {
		errno = EINVAL;
		return NULL;
	}
	char *output = strdup(value);
	if (output == NULL)
		RPMEMD_FATAL("!strdup");
	return output;
}
Exemple #6
0
/*
 * get_config_line -- (internal) read single line from file
 */
static int
get_config_line(FILE *file, char **line, uint64_t *line_max,
	uint8_t *line_max_increased, struct rpmemd_special_chars_pos *pos)
{
	uint8_t line_complete = 0;
	uint64_t line_length = 0;
	char *line_part = *line;
	do {
		char *ret = fgets(line_part,
			(int)(*line_max - line_length), file);
		if (ret == NULL)
			return 0;
		for (uint64_t i = 0; i < *line_max; ++i) {
			if (line_part[i] == '\n')
				line_complete = 1;
			else if (line_part[i] == '\0') {
				line_length += i;
				if (line_length + 1 < *line_max)
					line_complete = 1;
				break;
			} else if (line_part[i] == '#' &&
				pos->comment_char == UINT64_MAX)
				pos->comment_char = line_length + i;
			else if (line_part[i] == '=' &&
				pos->equal_char == UINT64_MAX)
				pos->equal_char = line_length + i;
		}
		if (line_complete == 0) {
			*line = realloc(*line, sizeof(char) * (*line_max) * 2);
			if (*line == NULL) {
				RPMEMD_FATAL("!realloc");
			}
			line_part = *line + *line_max - 1;
			line_length = *line_max - 1;
			*line_max *= 2;
			*line_max_increased = 1;
		}
	} while (line_complete != 1);

	pos->EOL_char = line_length;
	return 0;
}
Exemple #7
0
/*
 * rpmemd_apply_pm_policy -- choose the persistency method and the flush
 * function according to the pool type and the persistency method read from the
 * config
 */
int
rpmemd_apply_pm_policy(enum rpmem_persist_method *persist_method,
	int (**persist)(const void *addr, size_t len),
	void *(**memcpy_persist)(void *pmemdest, const void *src, size_t len),
	const int is_pmem)
{
	switch (*persist_method) {
	case RPMEM_PM_APM:
		if (is_pmem) {
			*persist_method = RPMEM_PM_APM;
			*persist = rpmemd_flush_fatal;
		} else {
			*persist_method = RPMEM_PM_GPSPM;
			*persist = pmem_msync;
		}
		break;
	case RPMEM_PM_GPSPM:
		*persist_method = RPMEM_PM_GPSPM;
		*persist = is_pmem ? rpmemd_pmem_persist : pmem_msync;
		break;
	default:
		RPMEMD_FATAL("invalid persist method: %d", *persist_method);
		return -1;
	}

	/* this is for RPMEM_PERSIST_INLINE */
	if (is_pmem)
		*memcpy_persist = pmem_memcpy_persist;
	else
		*memcpy_persist = rpmem_memcpy_msync;

	RPMEMD_LOG(NOTICE, "persistency policy:");
	rpmem_print_pm_policy(*persist_method, *persist);

	return 0;
}
Exemple #8
0
/*
 * rpmemd_log -- main logging function
 */
void
rpmemd_log(enum rpmemd_log_level level, const char *fname, int lineno,
	const char *fmt, ...)
{
	if (!rpmemd_use_syslog && level > rpmemd_log_level)
		return;

	char buff[RPMEMD_MAX_MSG];

	size_t cnt = 0;
	int ret;
	if (fname) {
		ret = snprintf(&buff[cnt], RPMEMD_MAX_MSG - cnt,
				"[%s:%d] ", basename(fname), lineno);
		if (ret < 0)
			RPMEMD_FATAL("snprintf failed");

		cnt += (size_t)ret;
	}
	if (rpmemd_prefix_buff[0]) {
		ret = snprintf(&buff[cnt], RPMEMD_MAX_MSG - cnt,
				"%s ", rpmemd_prefix_buff);
		if (ret < 0)
			RPMEMD_FATAL("snprintf failed");

		cnt += (size_t)ret;
	}

	const char *errorstr = "";
	const char *prefix = "";
	const char *suffix = "\n";
	if (fmt) {
		if (*fmt == '!') {
			fmt++;
			errorstr = strerror(errno);
			prefix = ": ";
		}
	}

	va_list ap;
	va_start(ap, fmt);
	ret = vsnprintf(&buff[cnt], RPMEMD_MAX_MSG - cnt, fmt, ap);
	va_end(ap);

	if (ret < 0)
		RPMEMD_FATAL("vsnprintf failed");

	cnt += (size_t)ret;

	ret = snprintf(&buff[cnt], RPMEMD_MAX_MSG - cnt,
			"%s%s%s", prefix, errorstr, suffix);
	if (ret < 0)
		RPMEMD_FATAL("snprintf failed");

	cnt += (size_t)ret;

	if (rpmemd_use_syslog) {
		int prio = rpmemd_level2prio[level];
		syslog(prio, "%s", buff);
	} else {
		fprintf(rpmemd_log_file, "%s", buff);
		fflush(rpmemd_log_file);
	}

}
Exemple #9
0
int
main(int argc, char *argv[])
{
	START(argc, argv, "rpmemd_log");

	if (argc < 4) {
		USAGE();
		return 1;
	}

	const char *log_op = argv[1];
	const char *log_type = argv[2];
	const char *file = argv[3];

	int do_fatal = 0;
	int do_assert = 0;
	if (strcmp(log_op, "fatal") == 0) {
		do_fatal = 1;
	} else if (strcmp(log_op, "assert") == 0) {
		do_assert = 1;
	} else if (strcmp(log_op, "log") == 0) {
	} else {
		USAGE();
		return 1;
	}

	enum test_log_type type;
	if (strcmp(log_type, "stdout") == 0) {
		type = TEST_STDOUT;
	} else if (strcmp(log_type, "file") == 0) {
		type = TEST_FILE;
	} else if (strcmp(log_type, "syslog") == 0) {
		type = TEST_SYSLOG;
	} else {
		USAGE();
		return 1;
	}

	int fd_stdout = -1;
	FILE *stdout_fh = NULL;
	switch (type) {
	case TEST_STDOUT:
		/*
		 * Duplicate stdout file descriptor in order to preserve
		 * the file list after redirecting the stdout to a file.
		 */
		fd_stdout = dup(1);
		UT_ASSERTne(fd_stdout, -1);
		close(1);
		stdout_fh = fopen(file, "a");
		UT_ASSERTne(stdout_fh, NULL);
		break;
	case TEST_SYSLOG:
		syslog_fh = fopen(file, "a");
		UT_ASSERTne(syslog_fh, NULL);
		break;
	default:
		break;
	}

	/*
	 * Check an invalid configuration
	 */
	int ret;
	ret = rpmemd_log_init("rpmemd_log", file, 1);
	UT_ASSERTne(ret, 0);

	switch (type) {
	case TEST_STDOUT:
		ret = rpmemd_log_init("rpmemd_log", NULL, 0);
		UT_ASSERTeq(ret, 0);
		break;
	case TEST_SYSLOG:
		ret = rpmemd_log_init("rpmemd_log", NULL, 1);
		UT_ASSERTeq(ret, 0);
		break;
	case TEST_FILE:
		ret = rpmemd_log_init("rpmemd_log", file, 0);
		UT_ASSERTeq(ret, 0);
		break;
	default:
		break;
	}

	if (do_fatal) {
		RPMEMD_FATAL("fatal");
	} else if (do_assert) {
		RPMEMD_ASSERT(1);
		RPMEMD_ASSERT(0);
	} else {
		test_all_log_messages();
	}

	rpmemd_log_close();

	switch (type) {
	case TEST_STDOUT:
		/* restore the original stdout file descriptor */
		fclose(stdout_fh);
		UT_ASSERTeq(dup2(fd_stdout, 1), 1);
		close(fd_stdout);
		break;
	case TEST_SYSLOG:
		fclose(syslog_fh);
		break;
	default:
		break;
	}

	DONE(NULL);
}
Exemple #10
0
/*
 * rpmemd_flush_fatal -- APM specific flush function which should never be
 * called because APM does not require flushes
 */
int
rpmemd_flush_fatal(const void *addr, size_t len)
{
	RPMEMD_FATAL("rpmemd_flush_fatal should never be called");
}