LIRC libraries
Linux Infrared Remote Control
Loading...
Searching...
No Matches
lirc_options.c
Go to the documentation of this file.
1/****************************************************************************
2** lirc_options.c **********************************************************
3****************************************************************************
4*
5* options.c - global options access.
6*
7*/
8
14#ifdef HAVE_CONFIG_H
15# include <config.h>
16#endif
17
18#include <getopt.h>
19#include <stdio.h>
20#include <stdlib.h>
21#if defined(__linux__)
22#include <linux/types.h>
23#endif
24
25#include "ciniparser.h"
26#include "lirc_options.h"
27#include "lirc_log.h"
28
29static const logchannel_t logchannel = LOG_LIB;
30
31dictionary* lirc_options = NULL;
32
33/* Environment variable which if set enables some debug output. */
34static const char* const LIRC_DEBUG_OPTIONS = "LIRC_DEBUG_OPTIONS";
35
36static int depth = 0;
37
38static int options_debug = -1;
39
41{
42 char s[4];
43 loglevel_t level;
44
45 level = string2loglevel(optarg);
46 if (level == LIRC_BADLEVEL)
47 return level;
48 snprintf(s, sizeof(s), "%d", level);
49 options_set_opt("lircd:debug", s);
50 return level;
51}
52
53
54void options_set_opt(const char* key, const char* value)
55{
56 if (dictionary_set(lirc_options, key, value) != 0)
57 log_warn("Cannot set option %s to %s\n", key, value);
58}
59
60
61const char* options_getstring(const char* const key)
62{
63 return ciniparser_getstring(lirc_options, key, 0);
64}
65
66
67int options_getint(const char* const key)
68{
69 return ciniparser_getint(lirc_options, key, 0);
70}
71
72
73int options_getboolean(const char* const key)
74{
75 return ciniparser_getboolean(lirc_options, key, 0);
76}
77
78
79static char* parse_O_arg(int argc, char** argv)
80{
81 char* path = NULL;
82 int i;
83 const int opt_len = strlen("--options_file");
84
85 for (i = 0; i < argc; i += 1) {
86 if (strncmp(argv[i], "-O", 2) != 0 &&
87 strncmp(argv[i], "--options-file", opt_len) != 0)
88 continue;
89 if (strchr(argv[i], '=') != NULL) {
90 path = strchr(argv[i], '=') + 1;
91 } else if (strncmp(argv[i], "-O", 2) == 0 &&
92 strlen(argv[i]) > 2
93 ) {
94 path = argv[i] + 2;
95 } else if (i + 1 < argc) {
96 path = argv[i + 1];
97 } else {
98 return NULL;
99 }
100 if (path && access(path, R_OK) != 0) {
101 fprintf(stderr, "Cannot open options file %s for read\n",
102 path);
103 return NULL;
104 }
105 return path;
106 }
107 return NULL;
108}
109
110
111void options_load(int argc, char** const argv,
112 const char* path_arg,
113 void (*parse_options)(int, char** const))
114{
115 char buff[128];
116 char buff2[128];
117 const char* path = path_arg;
118
119 if (depth > 1) {
120 log_warn("Error:Cowardly refusing to process"
121 " options-file option within a file\n");
122 return;
123 }
124 depth += 1;
125 setenv("POSIXLY_CORRECT", "1", 1);
126 if (path == NULL)
127 path = parse_O_arg(argc, argv);
128 if (path == NULL) {
129 path = getenv(LIRC_OPTIONS_VAR);
130 path = (path == NULL ? LIRC_OPTIONS_PATH : path);
131 }
132 if (*path != '/') {
133 if (getcwd(buff2, sizeof(buff2)) == NULL)
134 log_perror_warn("options_load: getcwd():");
135 snprintf(buff, sizeof(buff), "%s/%s", buff2, path);
136 path = buff;
137 }
138 if (access(path, R_OK) == 0) {
139 lirc_options = ciniparser_load(path);
140 if (lirc_options == NULL) {
141 log_warn("Cannot load options file %s\n", path);
142 lirc_options = dictionary_new(0);
143 }
144 } else {
145 fprintf(stderr, "Warning: cannot open %s\n", path);
146 log_warn("Cannot open %s\n", path);
147 lirc_options = dictionary_new(0);
148 }
149 if (parse_options != NULL)
150 parse_options(argc, argv);
151 if (options_debug == -1)
152 options_debug = getenv(LIRC_DEBUG_OPTIONS) != NULL;
153 if (options_debug && lirc_options != NULL) {
154 fprintf(stderr, "Dumping parsed option values:\n");
155 ciniparser_dump(lirc_options, stderr);
156 }
157}
158
159
161{
162 const char* s;
163 loglevel_t level = LIRC_BADLEVEL;
164 char buff[64];
165
166 s = getenv("LIRC_LOGLEVEL");
167 level = string2loglevel(s);
168 if (level != LIRC_BADLEVEL)
169 return level;
170 if (lirc_options == NULL)
171 options_load(0, NULL, NULL, NULL);
172 if (level == LIRC_BADLEVEL && app != NULL) {
173 snprintf(buff, sizeof(buff), "%s:debug", app);
174 s = ciniparser_getstring(lirc_options, buff, NULL);
175 level = string2loglevel(s);
176 }
177 if (level == LIRC_BADLEVEL) {
178 s = ciniparser_getstring(lirc_options, "lircd:debug", "debug");
179 level = string2loglevel(s);
180 if (level == LIRC_BADLEVEL)
181 level = LIRC_DEBUG;
182 }
183 return level;
184}
185
186
187void options_add_defaults(const char* const defaults[])
188{
189 int i;
190 const char* key;
191 const char* value;
192
193 for (i = 0; defaults[i] != NULL; i += 2) {
194 key = defaults[i];
195 value = defaults[i + 1];
196 if (ciniparser_getstring(lirc_options, key, NULL) == NULL)
197 options_set_opt((char*)key, (char*)value);
198 }
199}
200
201void options_unload(void)
202{
203 depth = 0;
204 options_debug = -1;
205 if (lirc_options != NULL) {
206 dictionary_del(lirc_options);
207 lirc_options = NULL;
208 }
209}
Parser for ini files.
dictionary * ciniparser_load(const char *ininame)
Parse an ini file and return an allocated dictionary object.
Definition ciniparser.c:368
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
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 * dictionary_new(int size)
Create a new dictionary object.
Definition dictionary.c:92
void dictionary_del(dictionary *d)
Delete a dictionary object.
Definition dictionary.c:109
int dictionary_set(dictionary *d, const char *key, const char *val)
Set a value in a dictionary.
Definition dictionary.c:147
void ciniparser_dump(dictionary *d, FILE *f)
Dump a dictionary to an opened file pointer.
Definition ciniparser.c:227
const char * ciniparser_getstring(dictionary *d, const char *key, char *def)
Get the string associated to a key.
Definition ciniparser.c:286
#define LIRC_OPTIONS_PATH
Default options file path.
Definition lirc_config.h:69
loglevel_t string2loglevel(const char *s)
Convert a string, either a number or 'info', 'trace1', error etc.
Definition lirc_log.c:234
Logging functionality.
loglevel_t
The defined loglevels.
Definition lirc_log.h:36
#define log_perror_warn(fmt,...)
perror wrapper logging with level LIRC_WARNING.
Definition lirc_log.h:94
logchannel_t
Log channels used to filter messages.
Definition lirc_log.h:53
#define log_warn(fmt,...)
Log a warning message.
Definition lirc_log.h:109
loglevel_t options_set_loglevel(const char *optarg)
Parse and store a loglevel, returning value (possibly LIRC_BADLEVEL).
loglevel_t options_get_app_loglevel(const char *app)
Return loglevel based on (falling priority)
Options management: options file, parse and retrieve.
Dictionary object.
Definition dictionary.h:67