Loading...
Searching...
No Matches
lirc_options.c
Go to the documentation of this file.
/****************************************************************************
** lirc_options.c **********************************************************
****************************************************************************
*
* options.c - global options access.
*
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#if defined(__linux__)
#include <linux/types.h>
#endif
#include "ciniparser.h"
#include "lirc_options.h"
#include "lirc_log.h"
static const logchannel_t logchannel = LOG_LIB;
dictionary* lirc_options = NULL;
/* Environment variable which if set enables some debug output. */
static const char* const LIRC_DEBUG_OPTIONS = "LIRC_DEBUG_OPTIONS";
static int depth = 0;
static int options_debug = -1;
loglevel_t options_set_loglevel(const char* optarg)
{
char s[4];
loglevel_t level;
level = string2loglevel(optarg);
if (level == LIRC_BADLEVEL)
return level;
snprintf(s, sizeof(s), "%d", level);
options_set_opt("lircd:debug", s);
return level;
}
void options_set_opt(const char* key, const char* value)
{
if (dictionary_set(lirc_options, key, value) != 0)
log_warn("Cannot set option %s to %s\n", key, value);
}
const char* options_getstring(const char* const key)
{
return ciniparser_getstring(lirc_options, key, 0);
}
int options_getint(const char* const key)
{
return ciniparser_getint(lirc_options, key, 0);
}
int options_getboolean(const char* const key)
{
return ciniparser_getboolean(lirc_options, key, 0);
}
static char* parse_O_arg(int argc, char** argv)
{
char* path = NULL;
int i;
const int opt_len = strlen("--options_file");
for (i = 0; i < argc; i += 1) {
if (strncmp(argv[i], "-O", 2) != 0 &&
strncmp(argv[i], "--options-file", opt_len) != 0)
continue;
if (strchr(argv[i], '=') != NULL) {
path = strchr(argv[i], '=') + 1;
} else if (strncmp(argv[i], "-O", 2) == 0 &&
strlen(argv[i]) > 2
) {
path = argv[i] + 2;
} else if (i + 1 < argc) {
path = argv[i + 1];
} else {
return NULL;
}
if (path && access(path, R_OK) != 0) {
fprintf(stderr, "Cannot open options file %s for read\n",
path);
return NULL;
}
return path;
}
return NULL;
}
void options_load(int argc, char** const argv,
const char* path_arg,
void (*parse_options)(int, char** const))
{
char buff[128];
char buff2[128];
const char* path = path_arg;
if (depth > 1) {
log_warn("Error:Cowardly refusing to process"
" options-file option within a file\n");
return;
}
depth += 1;
setenv("POSIXLY_CORRECT", "1", 1);
if (path == NULL)
path = parse_O_arg(argc, argv);
if (path == NULL) {
path = getenv(LIRC_OPTIONS_VAR);
path = (path == NULL ? LIRC_OPTIONS_PATH : path);
}
if (*path != '/') {
if (getcwd(buff2, sizeof(buff2)) == NULL)
log_perror_warn("options_load: getcwd():");
snprintf(buff, sizeof(buff), "%s/%s", buff2, path);
path = buff;
}
if (access(path, R_OK) == 0) {
lirc_options = ciniparser_load(path);
if (lirc_options == NULL) {
log_warn("Cannot load options file %s\n", path);
lirc_options = dictionary_new(0);
}
} else {
fprintf(stderr, "Warning: cannot open %s\n", path);
log_warn("Cannot open %s\n", path);
lirc_options = dictionary_new(0);
}
if (parse_options != NULL)
parse_options(argc, argv);
if (options_debug == -1)
options_debug = getenv(LIRC_DEBUG_OPTIONS) != NULL;
if (options_debug && lirc_options != NULL) {
fprintf(stderr, "Dumping parsed option values:\n");
ciniparser_dump(lirc_options, stderr);
}
}
loglevel_t options_get_app_loglevel(const char* app)
{
const char* s;
loglevel_t level = LIRC_BADLEVEL;
char buff[64];
s = getenv("LIRC_LOGLEVEL");
level = string2loglevel(s);
if (level != LIRC_BADLEVEL)
return level;
if (lirc_options == NULL)
options_load(0, NULL, NULL, NULL);
if (level == LIRC_BADLEVEL && app != NULL) {
snprintf(buff, sizeof(buff), "%s:debug", app);
s = ciniparser_getstring(lirc_options, buff, NULL);
level = string2loglevel(s);
}
if (level == LIRC_BADLEVEL) {
s = ciniparser_getstring(lirc_options, "lircd:debug", "debug");
level = string2loglevel(s);
if (level == LIRC_BADLEVEL)
level = LIRC_DEBUG;
}
return level;
}
void options_add_defaults(const char* const defaults[])
{
int i;
const char* key;
const char* value;
for (i = 0; defaults[i] != NULL; i += 2) {
key = defaults[i];
value = defaults[i + 1];
if (ciniparser_getstring(lirc_options, key, NULL) == NULL)
options_set_opt((char*)key, (char*)value);
}
}
void options_unload(void)
{
depth = 0;
options_debug = -1;
if (lirc_options != NULL) {
dictionary_del(lirc_options);
lirc_options = NULL;
}
}
ciniparser.h
Parser for ini files.
ciniparser_load
dictionary * ciniparser_load(const char *ininame)
Parse an ini file and return an allocated dictionary object.
Definition ciniparser.c:368
ciniparser_getboolean
int ciniparser_getboolean(dictionary *d, const char *key, int notfound)
Get the string associated to a key, convert to a boolean.
Definition ciniparser.c:324
dictionary
struct _dictionary_ dictionary
Dictionary object.
ciniparser_getint
int ciniparser_getint(dictionary *d, const char *key, int notfound)
Get the string associated to a key, convert to an int.
Definition ciniparser.c:300
dictionary_new
dictionary * dictionary_new(int size)
Create a new dictionary object.
Definition dictionary.c:92
dictionary_del
void dictionary_del(dictionary *d)
Delete a dictionary object.
Definition dictionary.c:109
dictionary_set
int dictionary_set(dictionary *d, const char *key, const char *val)
Set a value in a dictionary.
Definition dictionary.c:147
ciniparser_dump
void ciniparser_dump(dictionary *d, FILE *f)
Dump a dictionary to an opened file pointer.
Definition ciniparser.c:227
ciniparser_getstring
const char * ciniparser_getstring(dictionary *d, const char *key, char *def)
Get the string associated to a key.
Definition ciniparser.c:286
LIRC_OPTIONS_PATH
#define LIRC_OPTIONS_PATH
Default options file path.
Definition lirc_config.h:69
string2loglevel
loglevel_t string2loglevel(const char *s)
Convert a string, either a number or 'info', 'trace1', error etc.
Definition lirc_log.c:234
lirc_log.h
Logging functionality.
loglevel_t
loglevel_t
The defined loglevels.
Definition lirc_log.h:36
log_perror_warn
#define log_perror_warn(fmt,...)
perror wrapper logging with level LIRC_WARNING.
Definition lirc_log.h:94
logchannel_t
logchannel_t
Log channels used to filter messages.
Definition lirc_log.h:53
log_warn
#define log_warn(fmt,...)
Log a warning message.
Definition lirc_log.h:109
options_set_loglevel
loglevel_t options_set_loglevel(const char *optarg)
Parse and store a loglevel, returning value (possibly LIRC_BADLEVEL).
Definition lirc_options.c:40
options_get_app_loglevel
loglevel_t options_get_app_loglevel(const char *app)
Return loglevel based on (falling priority).
Definition lirc_options.c:160
lirc_options.h
Options management: options file, parse and retrieve.