LIRC libraries
LinuxInfraredRemoteControl
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 
29 static const logchannel_t logchannel = LOG_LIB;
30 
31 dictionary* lirc_options = NULL;
32 
33 /* Environment variable which if set enables some debug output. */
34 static const char* const LIRC_DEBUG_OPTIONS = "LIRC_DEBUG_OPTIONS";
35 
36 static int depth = 0;
37 
38 static int options_debug = -1;
39 
40 loglevel_t options_set_loglevel(const char* optarg)
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 
54 void 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 
61 const char* options_getstring(const char* const key)
62 {
63  return ciniparser_getstring(lirc_options, key, 0);
64 }
65 
66 
67 int options_getint(const char* const key)
68 {
69  return ciniparser_getint(lirc_options, key, 0);
70 }
71 
72 
73 int options_getboolean(const char* const key)
74 {
75  return ciniparser_getboolean(lirc_options, key, 0);
76 }
77 
78 static const struct option o_option[] = {
79  { "options-file", required_argument, NULL, 'O' },
80  { 0, 0, 0, 0 }
81 };
82 
83 
84 static char* parse_O_arg(int argc, char** argv)
85 {
86  char* path = NULL;
87  int i;
88 
89  for (i = 0; i < argc; i += 1) {
90  if (strcmp(argv[i], "-O") != 0 &&
91  strcmp(argv[i], "--options-file") != 0)
92  continue;
93  if (i + 1 >= argc)
94  return NULL;
95  path = argv[i + 1];
96  if (path && access(path, R_OK) != 0) {
97  fprintf(stderr, "Cannot open options file %s for read\n",
98  path);
99  return NULL;
100  }
101  return path;
102  }
103  return NULL;
104 }
105 
106 
107 void options_load(int argc, char** const argv,
108  const char* path_arg,
109  void (*parse_options)(int, char** const))
110 {
111  char buff[128];
112  char buff2[128];
113  const char* path = path_arg;
114 
115  if (depth > 1) {
116  log_warn("Error:Cowardly refusing to process"
117  " options-file option within a file\n");
118  return;
119  }
120  depth += 1;
121  setenv("POSIXLY_CORRECT", "1", 1);
122  if (path == NULL)
123  path = parse_O_arg(argc, argv);
124  if (path == NULL) {
125  path = getenv(LIRC_OPTIONS_VAR);
126  path = (path == NULL ? LIRC_OPTIONS_PATH : path);
127  }
128  if (*path != '/') {
129  if (getcwd(buff2, sizeof(buff2)) == NULL)
130  log_perror_warn("options_load: getcwd():");
131  snprintf(buff, sizeof(buff), "%s/%s", buff2, path);
132  path = buff;
133  }
134  if (access(path, R_OK) == 0) {
135  lirc_options = ciniparser_load(path);
136  if (lirc_options == NULL) {
137  log_warn("Cannot load options file %s\n", path);
138  lirc_options = dictionary_new(0);
139  }
140  } else {
141  fprintf(stderr, "Warning: cannot open %s\n", path);
142  log_warn("Cannot open %s\n", path);
143  lirc_options = dictionary_new(0);
144  }
145  if (parse_options != NULL)
146  parse_options(argc, argv);
147  if (options_debug == -1)
148  options_debug = getenv(LIRC_DEBUG_OPTIONS) != NULL;
149  if (options_debug && lirc_options != NULL) {
150  fprintf(stderr, "Dumping parsed option values:\n");
151  ciniparser_dump(lirc_options, stderr);
152  }
153 }
154 
155 
157 {
158  const char* s;
159  loglevel_t level = LIRC_BADLEVEL;
160  char buff[64];
161 
162  s = getenv("LIRC_LOGLEVEL");
163  level = string2loglevel(s);
164  if (level != LIRC_BADLEVEL)
165  return level;
166  if (lirc_options == NULL)
167  options_load(0, NULL, NULL, NULL);
168  if (level == LIRC_BADLEVEL && app != NULL) {
169  snprintf(buff, sizeof(buff), "%s:debug", app);
170  s = ciniparser_getstring(lirc_options, buff, NULL);
171  level = string2loglevel(s);
172  }
173  if (level == LIRC_BADLEVEL) {
174  s = ciniparser_getstring(lirc_options, "lircd:debug", "debug");
175  level = string2loglevel(s);
176  if (level == LIRC_BADLEVEL)
177  level = LIRC_DEBUG;
178  }
179  return level;
180 }
181 
182 
183 void options_add_defaults(const char* const defaults[])
184 {
185  int i;
186  const char* key;
187  const char* value;
188 
189  for (i = 0; defaults[i] != NULL; i += 2) {
190  key = defaults[i];
191  value = defaults[i + 1];
192  if (ciniparser_getstring(lirc_options, key, NULL) == NULL)
193  options_set_opt((char*)key, (char*)value);
194  }
195 }
196 
197 void options_unload(void)
198 {
199  depth = 0;
200  options_debug = -1;
201  if (lirc_options != NULL) {
202  dictionary_del(lirc_options);
203  lirc_options = NULL;
204  }
205 }
const char * ciniparser_getstring(dictionary *d, const char *key, char *def)
Get the string associated to a key.
Definition: ciniparser.c:286
int dictionary_set(dictionary *d, const char *key, const char *val)
Set a value in a dictionary.
Definition: dictionary.c:147
dictionary * ciniparser_load(const char *ininame)
Parse an ini file and return an allocated dictionary object.
Definition: ciniparser.c:368
Logging functionality.
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
Options management: options file, parse and retrieve.
#define log_warn(fmt,...)
Definition: lirc_log.h:109
loglevel_t options_set_loglevel(const char *optarg)
Definition: lirc_options.c:40
dictionary * dictionary_new(int size)
Create a new dictionary object.
Definition: dictionary.c:92
logchannel_t
Definition: lirc_log.h:53
loglevel_t
Definition: lirc_log.h:36
void dictionary_del(dictionary *d)
Delete a dictionary object.
Definition: dictionary.c:109
#define LIRC_OPTIONS_VAR
Definition: lirc_config.h:86
loglevel_t options_get_app_loglevel(const char *app)
Definition: lirc_options.c:156
#define LIRC_OPTIONS_PATH
Definition: lirc_config.h:83
void ciniparser_dump(dictionary *d, FILE *f)
Dump a dictionary to an opened file pointer.
Definition: ciniparser.c:227
Dictionary object.
Definition: dictionary.h:67
#define log_perror_warn(fmt,...)
Definition: lirc_log.h:94
Parser for ini files.
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
loglevel_t string2loglevel(const char *s)
Definition: lirc_log.c:233