summaryrefslogtreecommitdiffstats
path: root/lib/parse_ini.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/parse_ini.c')
-rw-r--r--lib/parse_ini.c112
1 files changed, 71 insertions, 41 deletions
diff --git a/lib/parse_ini.c b/lib/parse_ini.c
index 1289aae2..4c3c1b93 100644
--- a/lib/parse_ini.c
+++ b/lib/parse_ini.c
@@ -40,19 +40,22 @@ typedef struct {
40 char *stanza; 40 char *stanza;
41} np_ini_info; 41} np_ini_info;
42 42
43static char *default_ini_file_names[] = {"monitoring-plugins.ini", "plugins.ini", "nagios-plugins.ini", NULL}; 43static char *default_ini_file_names[] = {"monitoring-plugins.ini", "plugins.ini",
44 "nagios-plugins.ini", NULL};
44 45
45static char *default_ini_path_names[] = { 46static char *default_ini_path_names[] = {
46 "/usr/local/etc/monitoring-plugins/monitoring-plugins.ini", "/usr/local/etc/monitoring-plugins.ini", 47 "/usr/local/etc/monitoring-plugins/monitoring-plugins.ini",
47 "/etc/monitoring-plugins/monitoring-plugins.ini", "/etc/monitoring-plugins.ini", 48 "/usr/local/etc/monitoring-plugins.ini", "/etc/monitoring-plugins/monitoring-plugins.ini",
49 "/etc/monitoring-plugins.ini",
48 /* deprecated path names (for backward compatibility): */ 50 /* deprecated path names (for backward compatibility): */
49 "/etc/nagios/plugins.ini", "/usr/local/nagios/etc/plugins.ini", "/usr/local/etc/nagios/plugins.ini", "/etc/opt/nagios/plugins.ini", 51 "/etc/nagios/plugins.ini", "/usr/local/nagios/etc/plugins.ini",
50 "/etc/nagios-plugins.ini", "/usr/local/etc/nagios-plugins.ini", "/etc/opt/nagios-plugins.ini", NULL}; 52 "/usr/local/etc/nagios/plugins.ini", "/etc/opt/nagios/plugins.ini", "/etc/nagios-plugins.ini",
53 "/usr/local/etc/nagios-plugins.ini", "/etc/opt/nagios-plugins.ini", NULL};
51 54
52/* eat all characters from a FILE pointer until n is encountered */ 55/* eat all characters from a FILE pointer until n is encountered */
53#define GOBBLE_TO(f, c, n) \ 56#define GOBBLE_TO(f, c, n) \
54 do { \ 57 do { \
55 (c) = fgetc((f)); \ 58 (c) = fgetc((f)); \
56 } while ((c) != EOF && (c) != (n)) 59 } while ((c) != EOF && (c) != (n))
57 60
58/* internal function that returns the constructed defaults options */ 61/* internal function that returns the constructed defaults options */
@@ -87,8 +90,9 @@ static void parse_locator(const char *locator, const char *def_stanza, np_ini_in
87 i->stanza = strdup(def_stanza); 90 i->stanza = strdup(def_stanza);
88 } 91 }
89 92
90 if (i->stanza == NULL) 93 if (i->stanza == NULL) {
91 die(STATE_UNKNOWN, _("malloc() failed!\n")); 94 die(STATE_UNKNOWN, _("malloc() failed!\n"));
95 }
92 96
93 /* check whether there's an @file part */ 97 /* check whether there's an @file part */
94 if (stanza_len == locator_len) { 98 if (stanza_len == locator_len) {
@@ -99,8 +103,9 @@ static void parse_locator(const char *locator, const char *def_stanza, np_ini_in
99 i->file_string_on_heap = true; 103 i->file_string_on_heap = true;
100 } 104 }
101 105
102 if (i->file == NULL || i->file[0] == '\0') 106 if (i->file == NULL || i->file[0] == '\0') {
103 die(STATE_UNKNOWN, _("Cannot find config file in any standard location.\n")); 107 die(STATE_UNKNOWN, _("Cannot find config file in any standard location.\n"));
108 }
104} 109}
105 110
106/* 111/*
@@ -112,26 +117,31 @@ np_arg_list *np_get_defaults(const char *locator, const char *default_section) {
112 np_ini_info i; 117 np_ini_info i;
113 int is_suid_plugin = mp_suid(); 118 int is_suid_plugin = mp_suid();
114 119
115 if (is_suid_plugin && idpriv_temp_drop() == -1) 120 if (is_suid_plugin && idpriv_temp_drop() == -1) {
116 die(STATE_UNKNOWN, _("Cannot drop privileges: %s\n"), strerror(errno)); 121 die(STATE_UNKNOWN, _("Cannot drop privileges: %s\n"), strerror(errno));
122 }
117 123
118 parse_locator(locator, default_section, &i); 124 parse_locator(locator, default_section, &i);
119 inifile = strcmp(i.file, "-") == 0 ? stdin : fopen(i.file, "r"); 125 inifile = strcmp(i.file, "-") == 0 ? stdin : fopen(i.file, "r");
120 126
121 if (inifile == NULL) 127 if (inifile == NULL) {
122 die(STATE_UNKNOWN, _("Can't read config file: %s\n"), strerror(errno)); 128 die(STATE_UNKNOWN, _("Can't read config file: %s\n"), strerror(errno));
123 if (!read_defaults(inifile, i.stanza, &defaults)) 129 }
130 if (!read_defaults(inifile, i.stanza, &defaults)) {
124 die(STATE_UNKNOWN, _("Invalid section '%s' in config file '%s'\n"), i.stanza, i.file); 131 die(STATE_UNKNOWN, _("Invalid section '%s' in config file '%s'\n"), i.stanza, i.file);
132 }
125 133
126 if (i.file_string_on_heap) { 134 if (i.file_string_on_heap) {
127 free(i.file); 135 free(i.file);
128 } 136 }
129 137
130 if (inifile != stdin) 138 if (inifile != stdin) {
131 fclose(inifile); 139 fclose(inifile);
140 }
132 free(i.stanza); 141 free(i.stanza);
133 if (is_suid_plugin && idpriv_temp_restore() == -1) 142 if (is_suid_plugin && idpriv_temp_restore() == -1) {
134 die(STATE_UNKNOWN, _("Cannot restore privileges: %s\n"), strerror(errno)); 143 die(STATE_UNKNOWN, _("Cannot restore privileges: %s\n"), strerror(errno));
144 }
135 145
136 return defaults; 146 return defaults;
137} 147}
@@ -158,8 +168,9 @@ static int read_defaults(FILE *f, const char *stanza, np_arg_list **opts) {
158 /* our little stanza-parsing state machine */ 168 /* our little stanza-parsing state machine */
159 while ((c = fgetc(f)) != EOF) { 169 while ((c = fgetc(f)) != EOF) {
160 /* gobble up leading whitespace */ 170 /* gobble up leading whitespace */
161 if (isspace(c)) 171 if (isspace(c)) {
162 continue; 172 continue;
173 }
163 switch (c) { 174 switch (c) {
164 /* globble up comment lines */ 175 /* globble up comment lines */
165 case ';': 176 case ';':
@@ -172,9 +183,11 @@ static int read_defaults(FILE *f, const char *stanza, np_arg_list **opts) {
172 for (i = 0; i < stanza_len; i++) { 183 for (i = 0; i < stanza_len; i++) {
173 c = fgetc(f); 184 c = fgetc(f);
174 /* strip leading whitespace */ 185 /* strip leading whitespace */
175 if (i == 0) 186 if (i == 0) {
176 for (; isspace(c); c = fgetc(f)) 187 for (; isspace(c); c = fgetc(f)) {
177 continue; 188 continue;
189 }
190 }
178 /* nope, read to the end of the line */ 191 /* nope, read to the end of the line */
179 if (c != stanza[i]) { 192 if (c != stanza[i]) {
180 GOBBLE_TO(f, c, '\n'); 193 GOBBLE_TO(f, c, '\n');
@@ -185,10 +198,12 @@ static int read_defaults(FILE *f, const char *stanza, np_arg_list **opts) {
185 if (i == stanza_len) { 198 if (i == stanza_len) {
186 c = fgetc(f); 199 c = fgetc(f);
187 /* strip trailing whitespace */ 200 /* strip trailing whitespace */
188 for (; isspace(c); c = fgetc(f)) 201 for (; isspace(c); c = fgetc(f)) {
189 continue; 202 continue;
190 if (c == ']') 203 }
204 if (c == ']') {
191 stanzastate = RIGHTSTANZA; 205 stanzastate = RIGHTSTANZA;
206 }
192 } 207 }
193 break; 208 break;
194 /* otherwise, we're in the body of a stanza or a parse error */ 209 /* otherwise, we're in the body of a stanza or a parse error */
@@ -239,12 +254,13 @@ static int add_option(FILE *f, np_arg_list **optlst) {
239 if (linebuf == NULL || read_pos + read_sz >= linebuf_sz) { 254 if (linebuf == NULL || read_pos + read_sz >= linebuf_sz) {
240 linebuf_sz = linebuf_sz > 0 ? linebuf_sz << 1 : read_sz; 255 linebuf_sz = linebuf_sz > 0 ? linebuf_sz << 1 : read_sz;
241 linebuf = realloc(linebuf, linebuf_sz); 256 linebuf = realloc(linebuf, linebuf_sz);
242 if (linebuf == NULL) 257 if (linebuf == NULL) {
243 die(STATE_UNKNOWN, _("malloc() failed!\n")); 258 die(STATE_UNKNOWN, _("malloc() failed!\n"));
259 }
244 } 260 }
245 if (fgets(&linebuf[read_pos], (int)read_sz, f) == NULL) 261 if (fgets(&linebuf[read_pos], (int)read_sz, f) == NULL) {
246 done_reading = 1; 262 done_reading = 1;
247 else { 263 } else {
248 read_pos = strlen(linebuf); 264 read_pos = strlen(linebuf);
249 if (linebuf[read_pos - 1] == '\n') { 265 if (linebuf[read_pos - 1] == '\n') {
250 linebuf[--read_pos] = '\0'; 266 linebuf[--read_pos] = '\0';
@@ -256,38 +272,46 @@ static int add_option(FILE *f, np_arg_list **optlst) {
256 /* all that to read one line, isn't C fun? :) now comes the parsing :/ */ 272 /* all that to read one line, isn't C fun? :) now comes the parsing :/ */
257 273
258 /* skip leading whitespace */ 274 /* skip leading whitespace */
259 for (optptr = linebuf; optptr < lineend && isspace(*optptr); optptr++) 275 for (optptr = linebuf; optptr < lineend && isspace(*optptr); optptr++) {
260 continue; 276 continue;
277 }
261 /* continue to '=' or EOL, watching for spaces that might precede it */ 278 /* continue to '=' or EOL, watching for spaces that might precede it */
262 for (eqptr = optptr; eqptr < lineend && *eqptr != '='; eqptr++) { 279 for (eqptr = optptr; eqptr < lineend && *eqptr != '='; eqptr++) {
263 if (isspace(*eqptr) && optend == NULL) 280 if (isspace(*eqptr) && optend == NULL) {
264 optend = eqptr; 281 optend = eqptr;
265 else 282 } else {
266 optend = NULL; 283 optend = NULL;
284 }
267 } 285 }
268 if (optend == NULL) 286 if (optend == NULL) {
269 optend = eqptr; 287 optend = eqptr;
288 }
270 --optend; 289 --optend;
271 /* ^[[:space:]]*=foo is a syntax error */ 290 /* ^[[:space:]]*=foo is a syntax error */
272 if (optptr == eqptr) 291 if (optptr == eqptr) {
273 die(STATE_UNKNOWN, "%s\n", _("Config file error")); 292 die(STATE_UNKNOWN, "%s\n", _("Config file error"));
293 }
274 /* continue from '=' to start of value or EOL */ 294 /* continue from '=' to start of value or EOL */
275 for (valptr = eqptr + 1; valptr < lineend && isspace(*valptr); valptr++) 295 for (valptr = eqptr + 1; valptr < lineend && isspace(*valptr); valptr++) {
276 continue; 296 continue;
297 }
277 /* continue to the end of value */ 298 /* continue to the end of value */
278 for (valend = valptr; valend < lineend; valend++) 299 for (valend = valptr; valend < lineend; valend++) {
279 continue; 300 continue;
301 }
280 --valend; 302 --valend;
281 /* finally trim off trailing spaces */ 303 /* finally trim off trailing spaces */
282 for (; isspace(*valend); valend--) 304 for (; isspace(*valend); valend--) {
283 continue; 305 continue;
306 }
284 /* calculate the length of "--foo" */ 307 /* calculate the length of "--foo" */
285 opt_len = (size_t)(1 + optend - optptr); 308 opt_len = (size_t)(1 + optend - optptr);
286 /* 1-character params needs only one dash */ 309 /* 1-character params needs only one dash */
287 if (opt_len == 1) 310 if (opt_len == 1) {
288 cfg_len = 1 + (opt_len); 311 cfg_len = 1 + (opt_len);
289 else 312 } else {
290 cfg_len = 2 + (opt_len); 313 cfg_len = 2 + (opt_len);
314 }
291 /* if valptr<lineend then we have to also allocate space for "=bar" */ 315 /* if valptr<lineend then we have to also allocate space for "=bar" */
292 if (valptr < lineend) { 316 if (valptr < lineend) {
293 equals = value = 1; 317 equals = value = 1;
@@ -300,8 +324,9 @@ static int add_option(FILE *f, np_arg_list **optlst) {
300 cfg_len += 1; 324 cfg_len += 1;
301 } 325 }
302 /* a line with no equal sign isn't valid */ 326 /* a line with no equal sign isn't valid */
303 if (equals == 0) 327 if (equals == 0) {
304 die(STATE_UNKNOWN, "%s\n", _("Config file error")); 328 die(STATE_UNKNOWN, "%s\n", _("Config file error"));
329 }
305 330
306 /* okay, now we have all the info we need, so we create a new np_arg_list 331 /* okay, now we have all the info we need, so we create a new np_arg_list
307 * element and set the argument... 332 * element and set the argument...
@@ -329,11 +354,12 @@ static int add_option(FILE *f, np_arg_list **optlst) {
329 optnew->arg[read_pos] = '\0'; 354 optnew->arg[read_pos] = '\0';
330 355
331 /* ...and put that to the end of the list */ 356 /* ...and put that to the end of the list */
332 if (*optlst == NULL) 357 if (*optlst == NULL) {
333 *optlst = optnew; 358 *optlst = optnew;
334 else { 359 } else {
335 while (opttmp->next != NULL) 360 while (opttmp->next != NULL) {
336 opttmp = opttmp->next; 361 opttmp = opttmp->next;
362 }
337 opttmp->next = optnew; 363 opttmp->next = optnew;
338 } 364 }
339 365
@@ -344,7 +370,8 @@ static int add_option(FILE *f, np_arg_list **optlst) {
344static char *default_file(void) { 370static char *default_file(void) {
345 char *ini_file; 371 char *ini_file;
346 372
347 if ((ini_file = getenv("MP_CONFIG_FILE")) != NULL || (ini_file = default_file_in_path()) != NULL) { 373 if ((ini_file = getenv("MP_CONFIG_FILE")) != NULL ||
374 (ini_file = default_file_in_path()) != NULL) {
348 return ini_file; 375 return ini_file;
349 } 376 }
350 377
@@ -360,16 +387,19 @@ static char *default_file_in_path(void) {
360 char *config_path, **file; 387 char *config_path, **file;
361 char *dir, *ini_file, *tokens; 388 char *dir, *ini_file, *tokens;
362 389
363 if ((config_path = getenv("NAGIOS_CONFIG_PATH")) == NULL) 390 if ((config_path = getenv("NAGIOS_CONFIG_PATH")) == NULL) {
364 return NULL; 391 return NULL;
392 }
365 /* shall we spit out a warning that NAGIOS_CONFIG_PATH is deprecated? */ 393 /* shall we spit out a warning that NAGIOS_CONFIG_PATH is deprecated? */
366 394
367 if ((tokens = strdup(config_path)) == NULL) 395 if ((tokens = strdup(config_path)) == NULL) {
368 die(STATE_UNKNOWN, "%s\n", _("Insufficient Memory")); 396 die(STATE_UNKNOWN, "%s\n", _("Insufficient Memory"));
397 }
369 for (dir = strtok(tokens, ":"); dir != NULL; dir = strtok(NULL, ":")) { 398 for (dir = strtok(tokens, ":"); dir != NULL; dir = strtok(NULL, ":")) {
370 for (file = default_ini_file_names; *file != NULL; file++) { 399 for (file = default_ini_file_names; *file != NULL; file++) {
371 if ((asprintf(&ini_file, "%s/%s", dir, *file)) < 0) 400 if ((asprintf(&ini_file, "%s/%s", dir, *file)) < 0) {
372 die(STATE_UNKNOWN, "%s\n", _("Insufficient Memory")); 401 die(STATE_UNKNOWN, "%s\n", _("Insufficient Memory"));
402 }
373 if (access(ini_file, F_OK) == 0) { 403 if (access(ini_file, F_OK) == 0) {
374 free(tokens); 404 free(tokens);
375 return ini_file; 405 return ini_file;