diff options
author | Thomas Guyot-Sionnest <dermoth@aei.ca> | 2010-04-15 10:41:21 -0400 |
---|---|---|
committer | Thomas Guyot-Sionnest <dermoth@aei.ca> | 2010-04-21 22:39:44 -0400 |
commit | 47d04677b7a8b12b00e4f4c2a815514ad56b1239 (patch) | |
tree | 62bb1dfdde4bb5a0041de5665748863953fabcff /plugins | |
parent | 582034478b3ac7995f01a5f639c8d0604f3f432b (diff) | |
download | monitoring-plugins-47d04677b7a8b12b00e4f4c2a815514ad56b1239.tar.gz |
Replace the lousy multiline parser with a robust one.
This one counts double quotes and backslashes so it should handle any
level of escaping.
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/check_snmp.c | 57 |
1 files changed, 49 insertions, 8 deletions
diff --git a/plugins/check_snmp.c b/plugins/check_snmp.c index 19f78d03..6a44bc8c 100644 --- a/plugins/check_snmp.c +++ b/plugins/check_snmp.c | |||
@@ -59,6 +59,25 @@ const char *email = "nagiosplug-devel@lists.sourceforge.net"; | |||
59 | 59 | ||
60 | #define MAX_OIDS 8 | 60 | #define MAX_OIDS 8 |
61 | 61 | ||
62 | /* Gobble to string - stop incrementing c when c[0] match one of the | ||
63 | * characters in s */ | ||
64 | #define GOBBLE_TOS(c, s) while(c[0]!='\0' && strchr(s, c[0])==NULL) { c++; } | ||
65 | /* Given c, keep track of backslashes (bk) and double-quotes (dq) | ||
66 | * from c[0] */ | ||
67 | #define COUNT_SEQ(c, bk, dq) switch(c[0]) {\ | ||
68 | case '\\': \ | ||
69 | if (bk) bk--; \ | ||
70 | else bk++; \ | ||
71 | break; \ | ||
72 | case '"': \ | ||
73 | if (!dq) { dq++; } \ | ||
74 | else if(!bk) { dq--; } \ | ||
75 | else { bk--; } \ | ||
76 | break; \ | ||
77 | } | ||
78 | |||
79 | |||
80 | |||
62 | int process_arguments (int, char **); | 81 | int process_arguments (int, char **); |
63 | int validate_arguments (void); | 82 | int validate_arguments (void); |
64 | char *thisarg (char *str); | 83 | char *thisarg (char *str); |
@@ -118,6 +137,7 @@ int | |||
118 | main (int argc, char **argv) | 137 | main (int argc, char **argv) |
119 | { | 138 | { |
120 | int i, len, line; | 139 | int i, len, line; |
140 | unsigned int bk_count = 0, dq_count = 0; | ||
121 | int iresult = STATE_UNKNOWN; | 141 | int iresult = STATE_UNKNOWN; |
122 | int result = STATE_UNKNOWN; | 142 | int result = STATE_UNKNOWN; |
123 | int return_code = 0; | 143 | int return_code = 0; |
@@ -260,7 +280,7 @@ main (int argc, char **argv) | |||
260 | break; | 280 | break; |
261 | 281 | ||
262 | if (verbose > 2) { | 282 | if (verbose > 2) { |
263 | printf("Processing line %i\n oidname: %s\n response: %s\n", i+1, oidname, response); | 283 | printf("Processing oid %i (line %i)\n oidname: %s\n response: %s\n", i+1, line+1, oidname, response); |
264 | } | 284 | } |
265 | 285 | ||
266 | /* Clean up type array - Sol10 does not necessarily zero it out */ | 286 | /* Clean up type array - Sol10 does not necessarily zero it out */ |
@@ -284,15 +304,36 @@ main (int argc, char **argv) | |||
284 | else if (strstr (response, "STRING: ")) { | 304 | else if (strstr (response, "STRING: ")) { |
285 | show = strstr (response, "STRING: ") + 8; | 305 | show = strstr (response, "STRING: ") + 8; |
286 | conv = "%.10g"; | 306 | conv = "%.10g"; |
307 | |||
287 | /* Get the rest of the string on multi-line strings */ | 308 | /* Get the rest of the string on multi-line strings */ |
288 | if (show[0] == '"' && (response[strlen(response)-1] != '\"' || response[strlen(response)-2] != '\\')) { | 309 | ptr = show; |
289 | /* Strip out unmatched double-quote */ | 310 | COUNT_SEQ(ptr, bk_count, dq_count) |
290 | if (show[0] == '"') show++; | 311 | while (dq_count && ptr[0] != '\n' && ptr[0] != '\0') { |
312 | ptr++; | ||
313 | GOBBLE_TOS(ptr, "\n\"\\") | ||
314 | COUNT_SEQ(ptr, bk_count, dq_count) | ||
315 | } | ||
316 | |||
317 | if (dq_count) { /* unfinished line */ | ||
318 | /* copy show verbatim first */ | ||
291 | if (!mult_resp) mult_resp = strdup(""); | 319 | if (!mult_resp) mult_resp = strdup(""); |
292 | asprintf (&mult_resp, "%s%s:\n%s\n", mult_resp, oids[i], strstr (response, "STRING: ") + 8); | 320 | asprintf (&mult_resp, "%s%s:\n%s\n", mult_resp, oids[i], show); |
321 | /* then strip out unmatched double-quote from single-line output */ | ||
322 | if (show[0] == '"') show++; | ||
323 | |||
324 | /* Keep reading until we match end of double-quoted string */ | ||
293 | for (line++; line < chld_out.lines; line++) { | 325 | for (line++; line < chld_out.lines; line++) { |
294 | asprintf (&mult_resp, "%s%s\n", mult_resp, chld_out.line[line]); | 326 | ptr = chld_out.line[line]; |
295 | if (mult_resp[strlen(mult_resp)-2] == '"' && response[strlen(response)-2] != '\\') break; | 327 | asprintf (&mult_resp, "%s%s\n", mult_resp, ptr); |
328 | |||
329 | COUNT_SEQ(ptr, bk_count, dq_count) | ||
330 | while (dq_count && ptr[0] != '\n' && ptr[0] != '\0') { | ||
331 | ptr++; | ||
332 | GOBBLE_TOS(ptr, "\n\"\\") | ||
333 | COUNT_SEQ(ptr, bk_count, dq_count) | ||
334 | } | ||
335 | /* Break for loop before next line increment when done */ | ||
336 | if (!dq_count) break; | ||
296 | } | 337 | } |
297 | } | 338 | } |
298 | 339 | ||
@@ -379,7 +420,7 @@ main (int argc, char **argv) | |||
379 | } | 420 | } |
380 | } | 421 | } |
381 | 422 | ||
382 | printf ("%s %s -%s %s \n", label, state_text (result), outbuff, perfstr); | 423 | printf ("%s %s -%s %s\n", label, state_text (result), outbuff, perfstr); |
383 | if (mult_resp) printf ("%s", mult_resp); | 424 | if (mult_resp) printf ("%s", mult_resp); |
384 | 425 | ||
385 | return result; | 426 | return result; |