LIRC libraries
LinuxInfraredRemoteControl
 All Data Structures Files Functions Variables Typedefs Enumerations Macros Groups Pages
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 dictionary* lirc_options = NULL;
30 
31 /* Environment variable which if set enables some debug output. */
32 static const char* const LIRC_DEBUG_OPTIONS = "LIRC_DEBUG_OPTIONS";
33 
34 static int depth = 0;
35 
36 static int options_debug = -1;
37 
38 loglevel_t options_set_loglevel(const char* optarg)
39 {
40  char s[4];
41  loglevel_t level;
42 
43  level = string2loglevel(optarg);
44  if (level == LIRC_BADLEVEL)
45  return level;
46  snprintf(s, sizeof(s), "%d", level);
47  options_set_opt("lircd:debug", s);
48  return level;
49 }
50 
51 
52 void options_set_opt(const char* key, const char* value)
53 {
54  if (dictionary_set(lirc_options, key, value) != 0)
55  logprintf(LIRC_WARNING,
56  "Cannot set option %s to %s\n", key, value);
57 }
58 
59 
60 const char* options_getstring(const char* const key)
61 {
62  return ciniparser_getstring(lirc_options, key, 0);
63 }
64 
65 
66 int options_getint(const char* const key)
67 {
68  return ciniparser_getint(lirc_options, key, 0);
69 }
70 
71 
72 int options_getboolean(const char* const key)
73 {
74  return ciniparser_getboolean(lirc_options, key, 0);
75 }
76 
77 static const struct option o_option[] = {
78  { "options-file", required_argument, NULL, 'O' },
79  { 0, 0, 0, 0 }
80 };
81 
82 
83 static char* parse_O_arg(int argc, char** argv)
84 {
85  int c;
86  char* path = NULL;
87 
88  opterr = 0;
89  optind = 1;
90  // This should really be "O:", but getopt_long seemingly cannot
91  // handle a single option in the string. The w is tolerated here,
92  // but it does not matter.
93  while ((c = getopt_long(argc, argv, "wO:", o_option, NULL)) != -1)
94  if (c == 'O')
95  path = optarg;
96  opterr = 1;
97  optind = 1;
98 
99  if (path && access(path, R_OK) != 0) {
100  fprintf(stderr, "Cannot open options file %s for read\n",
101  path);
102  return NULL;
103  }
104  return path;
105 }
106 
107 
108 void options_load(int argc, char** const argv,
109  const char* path_arg,
110  void (*parse_options)(int, char** const))
111 {
112  char buff[128];
113  char buff2[128];
114  const char* path = path_arg;
115 
116  if (depth > 1) {
117  logprintf(LIRC_WARNING,
118  "Error:Cowardly refusing to process"
119  " options-file option within a file\n");
120  return;
121  }
122  depth += 1;
123  setenv("POSIXLY_CORRECT", "1", 1);
124  if (path == NULL)
125  path = parse_O_arg(argc, argv);
126  if (path == NULL) {
127  path = getenv(LIRC_OPTIONS_VAR);
128  path = (path == NULL ? LIRC_OPTIONS_PATH : path);
129  }
130  if (*path != '/') {
131  if (getcwd(buff2, sizeof(buff2)) == NULL)
132  logperror(LIRC_WARNING, "options_load: getcwd():");
133  snprintf(buff, sizeof(buff), "%s/%s", buff2, path);
134  path = buff;
135  }
136  if (access(path, R_OK) == 0) {
137  lirc_options = ciniparser_load(path);
138  if (lirc_options == NULL) {
139  logprintf(LIRC_WARNING,
140  "Cannot load options file %s\n", path);
141  lirc_options = dictionary_new(0);
142  }
143  } else {
144  fprintf(stderr, "Warning: cannot open %s\n", path);
145  logprintf(LIRC_WARNING, "Cannot open %s\n", path);
146  lirc_options = dictionary_new(0);
147  }
148  parse_options(argc, argv);
149  if (options_debug == -1)
150  options_debug = getenv(LIRC_DEBUG_OPTIONS) != NULL;
151  if (options_debug && lirc_options != NULL) {
152  fprintf(stderr, "Dumping parsed option values:\n");
153  ciniparser_dump(lirc_options, stderr);
154  }
155 }
156 
157 
158 void options_add_defaults(const char* const defaults[])
159 {
160  int i;
161  const char* key;
162  const char* value;
163 
164  for (i = 0; defaults[i] != NULL; i += 2) {
165  key = defaults[i];
166  value = defaults[i + 1];
167  if (ciniparser_getstring(lirc_options, key, NULL) == NULL)
168  options_set_opt((char*)key, (char*)value);
169  }
170 }
171 
172 void options_unload(void)
173 {
174  depth = 0;
175  options_debug = -1;
176  if (lirc_options != NULL) {
177  dictionary_del(lirc_options);
178  lirc_options = NULL;
179  }
180 }
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.
loglevel_t options_set_loglevel(const char *optarg)
Definition: lirc_options.c:38
dictionary * dictionary_new(int size)
Create a new dictionary object.
Definition: dictionary.c:92
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
#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
void logperror(loglevel_t prio, const char *fmt,...)
Definition: lirc_log.c:288
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:216