diff options
Diffstat (limited to 'lib/parse_ini.c')
-rw-r--r-- | lib/parse_ini.c | 112 |
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 | ||
43 | static char *default_ini_file_names[] = {"monitoring-plugins.ini", "plugins.ini", "nagios-plugins.ini", NULL}; | 43 | static char *default_ini_file_names[] = {"monitoring-plugins.ini", "plugins.ini", |
44 | "nagios-plugins.ini", NULL}; | ||
44 | 45 | ||
45 | static char *default_ini_path_names[] = { | 46 | static 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) { | |||
344 | static char *default_file(void) { | 370 | static 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; |