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 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  level = string2loglevel(optarg);
43  if (level == LIRC_BADLEVEL)
44  return level;
45  snprintf(s, sizeof(s), "%d", level);
46  options_set_opt("lircd:debug", s);
47  return level;
48 }
49 
50 
51 void options_set_opt(const char* key, const char* value)
52 {
53  if (dictionary_set(lirc_options, key, value) != 0)
54  logprintf(LIRC_WARNING,
55  "Cannot set option %s to %s\n", key, value);
56 }
57 
58 
59 const char* options_getstring(const char* const key)
60 {
61  return ciniparser_getstring(lirc_options, key, 0);
62 }
63 
64 
65 int options_getint(const char* const key)
66 {
67  return ciniparser_getint(lirc_options, key, 0);
68 }
69 
70 
71 int options_getboolean(const char* const key)
72 {
73  return ciniparser_getboolean(lirc_options, key, 0);
74 }
75 
76 static const struct option o_option[] = {
77  {"options-file", required_argument, NULL, 'O'},
78  {0,0,0,0}
79 };
80 
81 
82 static char* parse_O_arg(int argc, char** argv)
83 {
84  int c;
85  char* path = NULL;
86 
87  opterr = 0;
88  optind = 1;
89  // This should really be "O:", but getopt_long seemingly cannot
90  // handle a single option in the string. The w is tolerated here,
91  // but it does not matter.
92  while ((c = getopt_long(argc, argv, "wO:", o_option, NULL)) != -1) {
93  if ( c == 'O')
94  path = optarg;
95  }
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  }
127  if (path == NULL) {
128  path = getenv( LIRC_OPTIONS_VAR );
129  path = (path == NULL ? LIRC_OPTIONS_PATH : path);
130  }
131  if (*path != '/') {
132  if (getcwd(buff2, sizeof(buff2)) == NULL) {
133  logperror(LIRC_WARNING, "options_load: getcwd():");
134  }
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  logprintf(LIRC_WARNING,
142  "Cannot load options file %s\n", path);
143  lirc_options = dictionary_new(0);
144  }
145  }
146  else {
147  fprintf(stderr, "Warning: cannot open %s\n", path);
148  logprintf(LIRC_WARNING, "Warning: cannot open %s\n", path);
149  lirc_options = dictionary_new(0);
150  }
151  parse_options(argc, argv);
152  if (options_debug == -1)
153  options_debug = getenv(LIRC_DEBUG_OPTIONS) != NULL;
154  if (options_debug && lirc_options != NULL ) {
155  fprintf(stderr, "Dumping parsed option values:\n" );
156  ciniparser_dump(lirc_options, stderr);
157  }
158 }
159 
160 
161 void options_add_defaults(const char* const defaults[])
162 {
163  int i;
164  const char* key;
165  const char* value;
166 
167  for(i = 0; defaults[i] != NULL; i += 2){
168  key = defaults[i];
169  value = defaults[i + 1];
170  if (ciniparser_getstring(lirc_options, key, NULL) == NULL)
171  options_set_opt((char*)key, (char*)value);
172  }
173 }
174 
175 void options_unload(void)
176 {
177  depth = 0;
178  options_debug = -1;
179  if (lirc_options != NULL ){
180  dictionary_del(lirc_options);
181  lirc_options = NULL;
182  }
183 }
const char * ciniparser_getstring(dictionary *d, const char *key, char *def)
Get the string associated to a key.
Definition: ciniparser.c:293
int dictionary_set(dictionary *d, const char *key, const char *val)
Set a value in a dictionary.
Definition: dictionary.c:149
dictionary * ciniparser_load(const char *ininame)
Parse an ini file and return an allocated dictionary object.
Definition: ciniparser.c:376
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:307
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:93
loglevel_t
Definition: lirc_log.h:37
void dictionary_del(dictionary *d)
Delete a dictionary object.
Definition: dictionary.c:110
#define LIRC_OPTIONS_VAR
Definition: lirc_config.h:88
#define LIRC_OPTIONS_PATH
Definition: lirc_config.h:85
void ciniparser_dump(dictionary *d, FILE *f)
Dump a dictionary to an opened file pointer.
Definition: ciniparser.c:229
Dictionary object.
Definition: dictionary.h:67
void logperror(loglevel_t prio, const char *fmt,...)
Definition: lirc_log.c:279
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:331
loglevel_t string2loglevel(const char *s)
Definition: lirc_log.c:207