Blame src/utils.c

Packit 7e09eb
/*
Packit 7e09eb
 * Intel(R) Enclosure LED Utilities
Packit 7e09eb
 * Copyright (C) 2009-2019 Intel Corporation.
Packit 7e09eb
 *
Packit 7e09eb
 * This program is free software; you can redistribute it and/or modify it
Packit 7e09eb
 * under the terms and conditions of the GNU General Public License,
Packit 7e09eb
 * version 2, as published by the Free Software Foundation.
Packit 7e09eb
 *
Packit 7e09eb
 * This program is distributed in the hope it will be useful, but WITHOUT
Packit 7e09eb
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
Packit 7e09eb
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
Packit 7e09eb
 * more details.
Packit 7e09eb
 *
Packit 7e09eb
 * You should have received a copy of the GNU General Public License along with
Packit 7e09eb
 * this program; if not, write to the Free Software Foundation, Inc.,
Packit 7e09eb
 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
Packit 7e09eb
 *
Packit 7e09eb
 */
Packit 7e09eb
Packit 7e09eb
#include <ctype.h>
Packit 7e09eb
#include <dirent.h>
Packit 7e09eb
#include <errno.h>
Packit 7e09eb
#include <fcntl.h>
Packit 7e09eb
#include <inttypes.h>
Packit 7e09eb
#include <libgen.h>
Packit 7e09eb
#include <limits.h>
Packit 7e09eb
#include <regex.h>
Packit 7e09eb
#include <stdarg.h>
Packit 7e09eb
#include <stdint.h>
Packit 7e09eb
#include <stdio.h>
Packit 7e09eb
#include <string.h>
Packit 7e09eb
#include <sys/stat.h>
Packit 7e09eb
#include <sys/time.h>
Packit 7e09eb
#include <sys/types.h>
Packit 7e09eb
#include <time.h>
Packit 7e09eb
#include <unistd.h>
Packit 7e09eb
Packit 7e09eb
#if _HAVE_DMALLOC_H
Packit 7e09eb
#include <dmalloc.h>
Packit 7e09eb
#endif
Packit 7e09eb
Packit 7e09eb
#include "config.h"
Packit 7e09eb
#include "list.h"
Packit 7e09eb
#include "status.h"
Packit 7e09eb
#include "utils.h"
Packit 7e09eb
Packit 7e09eb
/**
Packit 7e09eb
 */
Packit 7e09eb
#define TIMESTAMP_PATTERN    "%b %d %T "
Packit 7e09eb
Packit 7e09eb
/**
Packit 7e09eb
 * Name of the executable. It is the last section of invocation path.
Packit 7e09eb
 */
Packit 7e09eb
char *progname = NULL;
Packit 7e09eb
Packit 7e09eb
/**
Packit 7e09eb
 */
Packit 7e09eb
static FILE *s_log = NULL;
Packit 7e09eb
Packit 7e09eb
struct log_level_info log_level_infos[] = {
Packit 7e09eb
		[LOG_LEVEL_DEBUG] = {PREFIX_DEBUG, LOG_DEBUG},
Packit 7e09eb
		[LOG_LEVEL_WARNING] = {PREFIX_WARNING, LOG_WARNING},
Packit 7e09eb
		[LOG_LEVEL_INFO] = {PREFIX_INFO, LOG_INFO},
Packit 7e09eb
		[LOG_LEVEL_ERROR] = {PREFIX_ERROR, LOG_ERR}
Packit 7e09eb
};
Packit 7e09eb
Packit 7e09eb
/*
Packit 7e09eb
 * Function returns a content of a text file. See utils.h for details.
Packit 7e09eb
 */
Packit 7e09eb
char *get_text(const char *path, const char *name)
Packit 7e09eb
{
Packit 7e09eb
	char temp[PATH_MAX];
Packit 7e09eb
Packit 7e09eb
	snprintf(temp, sizeof(temp), "%s/%s", path, name);
Packit 7e09eb
	return buf_read(temp);
Packit 7e09eb
}
Packit 7e09eb
Packit 7e09eb
/*
Packit 7e09eb
 * Function returns integer value (1 or 0) based on a boolean value ('Y' or 'N')
Packit 7e09eb
 * read from a text file. See utils.h for details.
Packit 7e09eb
 */
Packit 7e09eb
int get_bool(const char *path, int defval, const char *name)
Packit 7e09eb
{
Packit 7e09eb
	char *p = get_text(path, name);
Packit 7e09eb
	if (p) {
Packit 7e09eb
		if (*p == 'Y')
Packit 7e09eb
			defval = 1;
Packit 7e09eb
		else if (*p == 'N')
Packit 7e09eb
			defval = 0;
Packit 7e09eb
		free(p);
Packit 7e09eb
	}
Packit 7e09eb
	return defval;
Packit 7e09eb
}
Packit 7e09eb
Packit 7e09eb
/*
Packit 7e09eb
 * Function returns 64-bit unsigned integer value read from a text file. See
Packit 7e09eb
 * utils.h for details.
Packit 7e09eb
 */
Packit 7e09eb
uint64_t get_uint64(const char *path, uint64_t defval, const char *name)
Packit 7e09eb
{
Packit 7e09eb
	char *p = get_text(path, name);
Packit 7e09eb
	uint64_t retval = defval;
Packit 7e09eb
Packit 7e09eb
	if (p) {
Packit 7e09eb
		if (sscanf(p, "%" SCNx64, &defval) == 1)
Packit 7e09eb
			retval = defval;
Packit 7e09eb
		free(p);
Packit 7e09eb
	}
Packit 7e09eb
	return retval;
Packit 7e09eb
}
Packit 7e09eb
Packit 7e09eb
/*
Packit 7e09eb
 * Function returns integer value read from a text file.
Packit 7e09eb
 * See utils.h for details.
Packit 7e09eb
 */
Packit 7e09eb
int get_int(const char *path, int defval, const char *name)
Packit 7e09eb
{
Packit 7e09eb
	char *p = get_text(path, name);
Packit 7e09eb
	if (p) {
Packit 7e09eb
		defval = atoi(p);
Packit 7e09eb
		free(p);
Packit 7e09eb
	}
Packit 7e09eb
	return defval;
Packit 7e09eb
}
Packit 7e09eb
Packit 7e09eb
/**
Packit 7e09eb
 */
Packit 7e09eb
int scan_dir(const char *path, struct list *result)
Packit 7e09eb
{
Packit 7e09eb
	struct dirent *dirent;
Packit 7e09eb
	int ret = 0;
Packit 7e09eb
	DIR *dir = opendir(path);
Packit 7e09eb
	if (!dir)
Packit 7e09eb
		return -1;
Packit 7e09eb
Packit 7e09eb
	list_init(result, NULL);
Packit 7e09eb
Packit 7e09eb
	while ((dirent = readdir(dir)) != NULL) {
Packit 7e09eb
		char *str;
Packit 7e09eb
		size_t len;
Packit 7e09eb
Packit 7e09eb
		if ((strcmp(dirent->d_name, ".") == 0) ||
Packit 7e09eb
		    (strcmp(dirent->d_name, "..")) == 0)
Packit 7e09eb
			continue;
Packit 7e09eb
Packit 7e09eb
		len = strlen(path) + strlen(dirent->d_name) + 2;
Packit 7e09eb
		str = malloc(len);
Packit 7e09eb
		if (!str) {
Packit 7e09eb
			ret = -1;
Packit 7e09eb
			list_erase(result);
Packit 7e09eb
			break;
Packit 7e09eb
		}
Packit 7e09eb
Packit 7e09eb
		snprintf(str, len, "%s/%s", path, dirent->d_name);
Packit 7e09eb
Packit 7e09eb
		list_append(result, str);
Packit 7e09eb
	}
Packit 7e09eb
	closedir(dir);
Packit 7e09eb
Packit 7e09eb
	return ret;
Packit 7e09eb
}
Packit 7e09eb
Packit 7e09eb
/**
Packit 7e09eb
 */
Packit 7e09eb
static int _is_virtual(int dev_type)
Packit 7e09eb
{
Packit 7e09eb
	switch (dev_type) {
Packit 7e09eb
	case 0:		/* sysfs  */
Packit 7e09eb
	case 3:		/* procfs */
Packit 7e09eb
		return 1;
Packit 7e09eb
	}
Packit 7e09eb
	return 0;
Packit 7e09eb
}
Packit 7e09eb
Packit 7e09eb
/**
Packit 7e09eb
 */
Packit 7e09eb
ssize_t buf_write(const char *path, const char *buf)
Packit 7e09eb
{
Packit 7e09eb
	int fd;
Packit 7e09eb
	ssize_t size = -1;
Packit 7e09eb
Packit 7e09eb
	if (path == NULL)
Packit 7e09eb
		__set_errno_and_return(EINVAL);
Packit 7e09eb
	if ((buf == NULL) || (strlen(buf) == 0))
Packit 7e09eb
		__set_errno_and_return(ENODATA);
Packit 7e09eb
	fd = open(path, O_WRONLY);
Packit 7e09eb
	if (fd >= 0) {
Packit 7e09eb
		size = write(fd, buf, strlen(buf));
Packit 7e09eb
		close(fd);
Packit 7e09eb
	}
Packit 7e09eb
	return size;
Packit 7e09eb
}
Packit 7e09eb
Packit 7e09eb
/**
Packit 7e09eb
 */
Packit 7e09eb
char *buf_read(const char *path)
Packit 7e09eb
{
Packit 7e09eb
	struct stat st;
Packit 7e09eb
	int fd, size;
Packit 7e09eb
	char *buf, *t;
Packit 7e09eb
Packit 7e09eb
	if (stat(path, &st) < 0)
Packit 7e09eb
		return NULL;
Packit 7e09eb
	if (st.st_size == 0) {
Packit 7e09eb
		if (!_is_virtual(st.st_dev))
Packit 7e09eb
			return NULL;
Packit 7e09eb
		st.st_size = st.st_blksize;
Packit 7e09eb
	}
Packit 7e09eb
	if (_is_virtual(st.st_dev))
Packit 7e09eb
		st.st_size = st.st_blksize;
Packit 7e09eb
	t = buf = malloc(st.st_size);
Packit 7e09eb
	if (buf) {
Packit 7e09eb
		fd = open(path, O_RDONLY);
Packit 7e09eb
		if (fd >= 0) {
Packit 7e09eb
			size = read(fd, buf, st.st_size);
Packit 7e09eb
			close(fd);
Packit 7e09eb
			if (size > 0)
Packit 7e09eb
				t = strchrnul(buf, '\n');
Packit 7e09eb
		}
Packit 7e09eb
		*t = '\0';
Packit 7e09eb
	}
Packit 7e09eb
	return buf;
Packit 7e09eb
}
Packit 7e09eb
Packit 7e09eb
/**
Packit 7e09eb
 */
Packit 7e09eb
void get_id(const char *path, struct device_id *did)
Packit 7e09eb
{
Packit 7e09eb
	char *t, *p;
Packit 7e09eb
Packit 7e09eb
	if (did && path) {
Packit 7e09eb
		did->major = did->minor = -1;
Packit 7e09eb
		p = buf_read(path);
Packit 7e09eb
		if (p) {
Packit 7e09eb
			t = strchr(p, ':');
Packit 7e09eb
			if (t) {
Packit 7e09eb
				*(t++) = '\0';
Packit 7e09eb
				did->major = atoi(p);
Packit 7e09eb
				did->minor = atoi(t);
Packit 7e09eb
			}
Packit 7e09eb
			free(p);
Packit 7e09eb
		}
Packit 7e09eb
	}
Packit 7e09eb
}
Packit 7e09eb
Packit 7e09eb
/**
Packit 7e09eb
 */
Packit 7e09eb
static void _log_timestamp(void)
Packit 7e09eb
{
Packit 7e09eb
	time_t timestamp;
Packit 7e09eb
	struct tm *t;
Packit 7e09eb
	char buf[30];
Packit 7e09eb
Packit 7e09eb
	timestamp = time(NULL);
Packit 7e09eb
	t = localtime(&timestamp);
Packit 7e09eb
Packit 7e09eb
	if (t) {
Packit 7e09eb
		strftime(buf, sizeof(buf), TIMESTAMP_PATTERN, t);
Packit 7e09eb
		fprintf(s_log, "%s", buf);
Packit 7e09eb
	}
Packit 7e09eb
}
Packit 7e09eb
Packit 7e09eb
/**
Packit 7e09eb
 */
Packit 7e09eb
int log_open(const char *path)
Packit 7e09eb
{
Packit 7e09eb
	if (s_log)
Packit 7e09eb
		log_close();
Packit 7e09eb
Packit 7e09eb
	s_log = fopen(path, "a");
Packit 7e09eb
	if (s_log == NULL)
Packit 7e09eb
		return -1;
Packit 7e09eb
	return 0;
Packit 7e09eb
}
Packit 7e09eb
Packit 7e09eb
/**
Packit 7e09eb
 */
Packit 7e09eb
void log_close(void)
Packit 7e09eb
{
Packit 7e09eb
	if (s_log) {
Packit 7e09eb
		fflush(s_log);
Packit 7e09eb
		fclose(s_log);
Packit 7e09eb
		s_log = NULL;
Packit 7e09eb
	}
Packit 7e09eb
}
Packit 7e09eb
Packit 7e09eb
/**
Packit 7e09eb
 */
Packit 7e09eb
void _log(enum log_level_enum loglevel, const char *buf,  ...)
Packit 7e09eb
{
Packit 7e09eb
	va_list vl;
Packit 7e09eb
	struct log_level_info *lli = &log_level_infos[loglevel];
Packit 7e09eb
Packit 7e09eb
	if (s_log == NULL)
Packit 7e09eb
		log_open(conf.log_path);
Packit 7e09eb
Packit 7e09eb
	if (conf.log_level >= loglevel) {
Packit 7e09eb
		char msg[4096];
Packit 7e09eb
		va_start(vl, buf);
Packit 7e09eb
		vsnprintf(msg, sizeof(msg), buf, vl);
Packit 7e09eb
		va_end(vl);
Packit 7e09eb
		if (s_log) {
Packit 7e09eb
			_log_timestamp();
Packit 7e09eb
			fprintf(s_log, "%s", lli->prefix);
Packit 7e09eb
			fprintf(s_log, "%s\n", msg);
Packit 7e09eb
			fflush(s_log);
Packit 7e09eb
		}
Packit 7e09eb
		syslog(lli->priority, "%s", msg);
Packit 7e09eb
	}
Packit 7e09eb
}
Packit 7e09eb
Packit 7e09eb
/**
Packit 7e09eb
 * @brief Sets program's short name.
Packit 7e09eb
 *
Packit 7e09eb
 * This is internal function of monitor service. It is used to extract the name
Packit 7e09eb
 * of executable file from command line argument.
Packit 7e09eb
 *
Packit 7e09eb
 * @param[in]     invocation_name - the pointer to command line argument
Packit 7e09eb
 *                                  with the invocation name.
Packit 7e09eb
 *
Packit 7e09eb
 * @return The function does not return a value.
Packit 7e09eb
 */
Packit 7e09eb
void set_invocation_name(char *invocation_name)
Packit 7e09eb
{
Packit 7e09eb
#ifdef program_invocation_short_name
Packit 7e09eb
	(void)invocation_name;
Packit 7e09eb
	progname = program_invocation_short_name;
Packit 7e09eb
#else
Packit 7e09eb
	char *t = strrchr(invocation_name, PATH_DELIM);
Packit 7e09eb
	if (t)
Packit 7e09eb
		progname = t + 1;
Packit 7e09eb
	else
Packit 7e09eb
		progname = invocation_name;
Packit 7e09eb
#endif				/* program_invocation_short_name */
Packit 7e09eb
}
Packit 7e09eb
Packit 7e09eb
/**
Packit 7e09eb
 */
Packit 7e09eb
char *str_cpy(char *dest, const char *src, size_t size)
Packit 7e09eb
{
Packit 7e09eb
	strncpy(dest, src, size - 1);
Packit 7e09eb
	dest[size - 1] = '\0';
Packit 7e09eb
	return dest;
Packit 7e09eb
}
Packit 7e09eb
Packit 7e09eb
/**
Packit 7e09eb
 */
Packit 7e09eb
char *str_dup(const char *src)
Packit 7e09eb
{
Packit 7e09eb
	char *ret;
Packit 7e09eb
Packit 7e09eb
	if (!src)
Packit 7e09eb
		return NULL;
Packit 7e09eb
	ret = strdup(src);
Packit 7e09eb
	if (!ret) {
Packit 7e09eb
		log_error("Cannot duplicate string");
Packit 7e09eb
		exit(EXIT_FAILURE);
Packit 7e09eb
	}
Packit 7e09eb
	return ret;
Packit 7e09eb
}
Packit 7e09eb
Packit 7e09eb
char *get_path_hostN(const char *path)
Packit 7e09eb
{
Packit 7e09eb
	char *c = NULL, *s = NULL, *p = str_dup(path);
Packit 7e09eb
	if (!p)
Packit 7e09eb
		return NULL;
Packit 7e09eb
	c = strstr(p, "host");
Packit 7e09eb
	if (!c)
Packit 7e09eb
		goto end;
Packit 7e09eb
	s = strchr(c, '/');
Packit 7e09eb
	if (!s)
Packit 7e09eb
		goto end;
Packit 7e09eb
	*s = 0;
Packit 7e09eb
	s = str_dup(c);
Packit 7e09eb
 end:
Packit 7e09eb
	free(p);
Packit 7e09eb
	return s;
Packit 7e09eb
}
Packit 7e09eb
Packit 7e09eb
char *get_path_component_rev(const char *path, int index)
Packit 7e09eb
{
Packit 7e09eb
	int i;
Packit 7e09eb
	char *c = NULL, *p = str_dup(path);
Packit 7e09eb
	char *result = NULL;
Packit 7e09eb
	for (i = 0; i <= index; i++) {
Packit 7e09eb
		if (c)
Packit 7e09eb
			*c = '\0';
Packit 7e09eb
		c = strrchr(p, '/');
Packit 7e09eb
	}
Packit 7e09eb
	if (c)
Packit 7e09eb
		result = str_dup(c + 1);
Packit 7e09eb
	free(p);
Packit 7e09eb
	return result;
Packit 7e09eb
}
Packit 7e09eb
Packit 7e09eb
char *truncate_path_component_rev(const char *path, int index)
Packit 7e09eb
{
Packit 7e09eb
	int i;
Packit 7e09eb
	char *c = NULL, *p = str_dup(path);
Packit 7e09eb
	if (!p)
Packit 7e09eb
		return NULL;
Packit 7e09eb
Packit 7e09eb
	for (i = 0; i <= index; i++) {
Packit 7e09eb
		if (c)
Packit 7e09eb
			*c = '\0';
Packit 7e09eb
		c = strrchr(p, '/');
Packit 7e09eb
	}
Packit 7e09eb
	c = str_dup(p);
Packit 7e09eb
	free(p);
Packit 7e09eb
	return c;
Packit 7e09eb
}
Packit 7e09eb
Packit 7e09eb
int match_string(const char *string, const char *pattern)
Packit 7e09eb
{
Packit 7e09eb
	int status;
Packit 7e09eb
	regex_t regex;
Packit 7e09eb
Packit 7e09eb
	if (!string || !pattern)
Packit 7e09eb
		return 0;
Packit 7e09eb
Packit 7e09eb
	if (strcmp(string, pattern) == 0)
Packit 7e09eb
		return 1;
Packit 7e09eb
Packit 7e09eb
	status = regcomp(&regex, pattern, REG_EXTENDED);
Packit 7e09eb
	if (status != 0) {
Packit 7e09eb
		log_debug("regecomp failed, ret=%d", status);
Packit 7e09eb
		return 0;
Packit 7e09eb
	}
Packit 7e09eb
Packit 7e09eb
	status = regexec(&regex, string, 0, NULL, 0);
Packit 7e09eb
	if (status != 0)
Packit 7e09eb
		return 0;
Packit 7e09eb
Packit 7e09eb
	return 1;
Packit 7e09eb
}
Packit 7e09eb
Packit 7e09eb
int get_log_fd(void)
Packit 7e09eb
{
Packit 7e09eb
	if (s_log)
Packit 7e09eb
		return fileno(s_log);
Packit 7e09eb
	return -1;
Packit 7e09eb
}
Packit 7e09eb
Packit 7e09eb
void print_opt(const char *long_opt, const char *short_opt, const char *desc)
Packit 7e09eb
{
Packit 7e09eb
	printf("%-20s%-10s%s\n", long_opt, short_opt, desc);
Packit 7e09eb
}
Packit 7e09eb
Packit 7e09eb
/**
Packit 7e09eb
 * @brief Sets the path to local log file.
Packit 7e09eb
 *
Packit 7e09eb
 * This function sets the path and
Packit 7e09eb
 * file name of log file. The function checks if the specified path is valid. In
Packit 7e09eb
 * case of incorrect path the function does nothing.
Packit 7e09eb
 *
Packit 7e09eb
 * @param[in]      path           new location and name of log file.
Packit 7e09eb
 *
Packit 7e09eb
 * @return STATUS_SUCCESS if successful, otherwise a valid status_t status code.
Packit 7e09eb
 *         The following status code are returned:
Packit 7e09eb
 *
Packit 7e09eb
 *         STATUS_INVALID_PATH    the given path is invalid.
Packit 7e09eb
 *         STATUS_FILE_OPEN_ERROR unable to open a log file i.e. because of
Packit 7e09eb
 *                                insufficient privileges.
Packit 7e09eb
 */
Packit 7e09eb
status_t set_log_path(const char *path)
Packit 7e09eb
{
Packit 7e09eb
	char temp[PATH_MAX];
Packit 7e09eb
	char log_file[PATH_MAX];
Packit 7e09eb
	char *resolved, *logdir, *logfile, *cpath;
Packit 7e09eb
Packit 7e09eb
	/*
Packit 7e09eb
	 * Extract directory from path
Packit 7e09eb
	 */
Packit 7e09eb
	cpath = str_dup(path);
Packit 7e09eb
	logdir = dirname(cpath);
Packit 7e09eb
Packit 7e09eb
	/*
Packit 7e09eb
	 * Check if directory exists
Packit 7e09eb
	 */
Packit 7e09eb
	resolved = realpath(logdir, temp);
Packit 7e09eb
	if (resolved == NULL) {
Packit 7e09eb
		printf("%s: %s\n", strerror(errno), logdir);
Packit 7e09eb
		free(cpath);
Packit 7e09eb
		return STATUS_INVALID_PATH;
Packit 7e09eb
	}
Packit 7e09eb
Packit 7e09eb
	free(cpath);
Packit 7e09eb
	cpath = str_dup(path);
Packit 7e09eb
	logfile = basename(cpath);
Packit 7e09eb
Packit 7e09eb
	snprintf(log_file, sizeof(log_file), "%s/%s",
Packit 7e09eb
		 resolved, logfile);
Packit 7e09eb
	free(cpath);
Packit 7e09eb
Packit 7e09eb
	if (conf.log_path)
Packit 7e09eb
		free(conf.log_path);
Packit 7e09eb
	conf.log_path = str_dup(log_file);
Packit 7e09eb
Packit 7e09eb
	return STATUS_SUCCESS;
Packit 7e09eb
}
Packit 7e09eb
Packit 7e09eb
/**
Packit 7e09eb
 * Internal array with option tokens. It is used to help parse command line
Packit 7e09eb
 * long options.
Packit 7e09eb
 */
Packit 7e09eb
struct option longopt_all[] = {
Packit 7e09eb
	[OPT_ALL]          = {"all", no_argument, NULL, '\0'},
Packit 7e09eb
	[OPT_CONFIG]       = {"config", required_argument, NULL, 'c'},
Packit 7e09eb
	[OPT_DEBUG]        = {"debug", no_argument, NULL, '\0'},
Packit 7e09eb
	[OPT_ERROR]        = {"error", no_argument, NULL, '\0'},
Packit 7e09eb
	[OPT_HELP]         = {"help", no_argument, NULL, 'h'},
Packit 7e09eb
	[OPT_INFO]         = {"info", no_argument, NULL, '\0'},
Packit 7e09eb
	[OPT_INTERVAL]     = {"interval", required_argument, NULL, 't'},
Packit 7e09eb
	[OPT_LOG]          = {"log", required_argument, NULL, 'l'},
Packit 7e09eb
	[OPT_QUIET]        = {"quiet", no_argument, NULL, '\0'},
Packit 7e09eb
	[OPT_VERSION]      = {"version", no_argument, NULL, 'v'},
Packit 7e09eb
	[OPT_WARNING]      = {"warning", no_argument, NULL, '\0'},
Packit 7e09eb
	[OPT_LOG_LEVEL]    = {"log-level", required_argument, NULL, '\0'},
Packit 7e09eb
	[OPT_LIST_CTRL]    = {"list-controllers", no_argument, NULL, 'L'},
Packit 7e09eb
	[OPT_LISTED_ONLY]  = {"listed-only", no_argument, NULL, 'x'},
Packit 7e09eb
	[OPT_FOREGROUND]   = {"foreground", no_argument, NULL, '\0'},
Packit 7e09eb
	[OPT_NULL_ELEMENT] = {NULL, no_argument, NULL, '\0'}
Packit 7e09eb
};
Packit 7e09eb
Packit 7e09eb
void setup_options(struct option **_longopt, char **_shortopt, int *options, int
Packit 7e09eb
		options_nr)
Packit 7e09eb
{
Packit 7e09eb
	struct option *longopt;
Packit 7e09eb
	char *shortopt;
Packit 7e09eb
	int i, j = 0;
Packit 7e09eb
	struct option *opt;
Packit 7e09eb
Packit 7e09eb
	longopt = malloc(sizeof(struct option) * (options_nr + 1));
Packit 7e09eb
	shortopt = calloc(options_nr * 2 + 1, sizeof(char));
Packit 7e09eb
	if (!longopt || !shortopt) {
Packit 7e09eb
		fprintf(stderr, "Out of memory\n");
Packit 7e09eb
		exit(STATUS_OUT_OF_MEMORY);
Packit 7e09eb
	}
Packit 7e09eb
	for (i = 0; i < options_nr; i++) {
Packit 7e09eb
		opt = &longopt_all[options[i]];
Packit 7e09eb
		longopt[i] = *opt;
Packit 7e09eb
		if (opt->val != '\0') {
Packit 7e09eb
			shortopt[j++] = (char) opt->val;
Packit 7e09eb
			if (opt->has_arg)
Packit 7e09eb
				shortopt[j++] = ':';
Packit 7e09eb
		}
Packit 7e09eb
	}
Packit 7e09eb
	longopt[i] = longopt_all[OPT_NULL_ELEMENT];
Packit 7e09eb
	shortopt[j] = '\0';
Packit 7e09eb
Packit 7e09eb
	*_longopt = longopt;
Packit 7e09eb
	*_shortopt = shortopt;
Packit 7e09eb
}
Packit 7e09eb
Packit 7e09eb
/**
Packit 7e09eb
 * @brief Gets id for given CLI option which corresponds to value from longopt
Packit 7e09eb
 * table.
Packit 7e09eb
 *
Packit 7e09eb
 * This is internal function of monitor service. The function maps given string
Packit 7e09eb
 * to the value from longopt enum and returns id of matched element. Generic
Packit 7e09eb
 * parameters allow to use this function for any CLI options-table which bases
Packit 7e09eb
 * on option struct.
Packit 7e09eb
 *
Packit 7e09eb
 * @param[in]     optarg          String containing value given by user in CLI.
Packit 7e09eb
 *
Packit 7e09eb
 * @return integer id if successful, otherwise a -1.
Packit 7e09eb
 */
Packit 7e09eb
int get_option_id(const char *optarg)
Packit 7e09eb
{
Packit 7e09eb
	int i = 0;
Packit 7e09eb
Packit 7e09eb
	while (longopt_all[i].name != NULL) {
Packit 7e09eb
		if (strcmp(longopt_all[i].name, optarg) == 0)
Packit 7e09eb
			return i;
Packit 7e09eb
		i++;
Packit 7e09eb
	}
Packit 7e09eb
	return -1;
Packit 7e09eb
}
Packit 7e09eb
Packit 7e09eb
Packit 7e09eb
/**
Packit 7e09eb
 * @brief Sets verbose variable to given level.
Packit 7e09eb
 *
Packit 7e09eb
 * This is internal function of monitor service. The function maps given level
Packit 7e09eb
 * to the value from verbose_level enum and sets verbose value to ledmon
Packit 7e09eb
 * configuration.
Packit 7e09eb
 *
Packit 7e09eb
 * @param[in]      log_level     required new log_level.
Packit 7e09eb
 *
Packit 7e09eb
 * @return STATUS_SUCCESS if successful, otherwise a valid status_t status code.
Packit 7e09eb
 */
Packit 7e09eb
status_t set_verbose_level(int log_level)
Packit 7e09eb
{
Packit 7e09eb
	int new_verbose = -1;
Packit 7e09eb
Packit 7e09eb
	switch (log_level) {
Packit 7e09eb
	case OPT_ALL:
Packit 7e09eb
		new_verbose = LOG_LEVEL_ALL;
Packit 7e09eb
		break;
Packit 7e09eb
	case OPT_DEBUG:
Packit 7e09eb
		new_verbose = LOG_LEVEL_DEBUG;
Packit 7e09eb
		break;
Packit 7e09eb
	case OPT_ERROR:
Packit 7e09eb
		new_verbose = LOG_LEVEL_ERROR;
Packit 7e09eb
		break;
Packit 7e09eb
	case OPT_INFO:
Packit 7e09eb
		new_verbose = LOG_LEVEL_INFO;
Packit 7e09eb
		break;
Packit 7e09eb
	case OPT_QUIET:
Packit 7e09eb
		new_verbose = LOG_LEVEL_QUIET;
Packit 7e09eb
		break;
Packit 7e09eb
	case OPT_WARNING:
Packit 7e09eb
		new_verbose = LOG_LEVEL_WARNING;
Packit 7e09eb
		break;
Packit 7e09eb
	}
Packit 7e09eb
	if (new_verbose != -1) {
Packit 7e09eb
		conf.log_level = new_verbose;
Packit 7e09eb
		return STATUS_SUCCESS;
Packit 7e09eb
	}
Packit 7e09eb
	return STATUS_CMDLINE_ERROR;
Packit 7e09eb
}
Packit 7e09eb
Packit 7e09eb
const char *ibpi2str(enum ibpi_pattern ibpi)
Packit 7e09eb
{
Packit 7e09eb
#ifdef _TEST_CONFIG
Packit 7e09eb
	return NULL;
Packit 7e09eb
#else
Packit 7e09eb
	static char buf[20];
Packit 7e09eb
	const char *ret;
Packit 7e09eb
Packit 7e09eb
	if (ibpi >= 0 && ibpi < ibpi_pattern_count)
Packit 7e09eb
		ret = ibpi_str[ibpi];
Packit 7e09eb
	else
Packit 7e09eb
		ret = NULL;
Packit 7e09eb
Packit 7e09eb
	if (!ret) {
Packit 7e09eb
		snprintf(buf, sizeof(buf), "(unknown: %u)", ibpi);
Packit 7e09eb
		ret = buf;
Packit 7e09eb
	}
Packit 7e09eb
Packit 7e09eb
	return ret;
Packit 7e09eb
#endif
Packit 7e09eb
}