summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Guyot-Sionnest <dermoth@aei.ca>2010-04-15 14:41:21 (GMT)
committerThomas Guyot-Sionnest <dermoth@aei.ca>2010-04-22 02:39:44 (GMT)
commit47d04677b7a8b12b00e4f4c2a815514ad56b1239 (patch)
tree62bb1dfdde4bb5a0041de5665748863953fabcff
parent582034478b3ac7995f01a5f639c8d0604f3f432b (diff)
downloadmonitoring-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.
-rw-r--r--plugins/check_snmp.c57
1 files changed, 49 insertions, 8 deletions
diff --git a/plugins/check_snmp.c b/plugins/check_snmp.c
index 19f78d0..6a44bc8 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
62int process_arguments (int, char **); 81int process_arguments (int, char **);
63int validate_arguments (void); 82int validate_arguments (void);
64char *thisarg (char *str); 83char *thisarg (char *str);
@@ -118,6 +137,7 @@ int
118main (int argc, char **argv) 137main (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;