[nagiosplug] Replace the lousy multiline parser with a robust ...

"Thomas Guyot-Sionnest" <[email protected]>
Newsgroups gmane.network.nagios.plugins.cvs
Message-ID <[email protected]>
 Module: nagiosplug
 Branch: master
 Commit: 47d04677b7a8b12b00e4f4c2a815514ad56b1239
 Author: Thomas Guyot-Sionnest <[email protected]>
   Date: Thu Apr 15 10:41:21 2010 -0400
    URL: http://nagiosplug.git.sf.net/git/gitweb.cgi?p=nagiosplug/nagiosplug;a=commit;h=47d0467

Replace the lousy multiline parser with a robust one.

This one counts double quotes and backslashes so it should handle any
level of escaping.

---

 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 19f78d0..6a44bc8 100644
--- a/plugins/check_snmp.c
+++ b/plugins/check_snmp.c
@@ -59,6 +59,25 @@ const char *email = "[email protected]";
 
 #define MAX_OIDS 8
 
+/* Gobble to string - stop incrementing c when c[0] match one of the
+ * characters in s */
+#define GOBBLE_TOS(c, s) while(c[0]!='\0' && strchr(s, c[0])==NULL) { c++; }
+/* Given c, keep track of backslashes (bk) and double-quotes (dq)
+ * from c[0] */
+#define COUNT_SEQ(c, bk, dq) switch(c[0]) {\
+	case '\\': \
+		if (bk) bk--; \
+		else bk++; \
+		break; \
+	case '"': \
+		if (!dq) { dq++; } \
+		else if(!bk) { dq--; } \
+		else { bk--; } \
+		break; \
+	}
+
+
+
 int process_arguments (int, char **);
 int validate_arguments (void);
 char *thisarg (char *str);
@@ -118,6 +137,7 @@ int
 main (int argc, char **argv)
 {
 	int i, len, line;
+	unsigned int bk_count = 0, dq_count = 0;
 	int iresult = STATE_UNKNOWN;
 	int result = STATE_UNKNOWN;
 	int return_code = 0;
@@ -260,7 +280,7 @@ main (int argc, char **argv)
 			break;
 
 		if (verbose > 2) {
-			printf("Processing line %i\n  oidname: %s\n  response: %s\n", i+1, oidname, response);
+			printf("Processing oid %i (line %i)\n  oidname: %s\n  response: %s\n", i+1, line+1, oidname, response);
 		}
 
 		/* Clean up type array - Sol10 does not necessarily zero it out */
@@ -284,15 +304,36 @@ main (int argc, char **argv)
 		else if (strstr (response, "STRING: ")) {
 			show = strstr (response, "STRING: ") + 8;
 			conv = "%.10g";
+
 			/* Get the rest of the string on multi-line strings */
-			if (show[0] == '"' && (response[strlen(response)-1] != '\"' || response[strlen(response)-2] != '\\')) {
-				/* Strip out unmatched double-quote */
-				if (show[0] == '"') show++;
+			ptr = show;
+			COUNT_SEQ(ptr, bk_count, dq_count)
+			while (dq_count && ptr[0] != '\n' && ptr[0] != '\0') {
+				ptr++;
+				GOBBLE_TOS(ptr, "\n\"\\")
+				COUNT_SEQ(ptr, bk_count, dq_count)
+			}
+
+			if (dq_count) { /* unfinished line */
+				/* copy show verbatim first */
 				if (!mult_resp) mult_resp = strdup("");
-				asprintf (&mult_resp, "%s%s:\n%s\n", mult_resp, oids[i], strstr (response, "STRING: ") + 8);
+				asprintf (&mult_resp, "%s%s:\n%s\n", mult_resp, oids[i], show);
+				/* then strip out unmatched double-quote from single-line output */
+				if (show[0] == '"') show++;
+
+				/* Keep reading until we match end of double-quoted string */
 				for (line++; line < chld_out.lines; line++) {
-					asprintf (&mult_resp, "%s%s\n", mult_resp, chld_out.line[line]);
-					if (mult_resp[strlen(mult_resp)-2] == '"' && response[strlen(response)-2] != '\\') break;
+					ptr = chld_out.line[line];
+					asprintf (&mult_resp, "%s%s\n", mult_resp, ptr);
+
+					COUNT_SEQ(ptr, bk_count, dq_count)
+					while (dq_count && ptr[0] != '\n' && ptr[0] != '\0') {
+						ptr++;
+						GOBBLE_TOS(ptr, "\n\"\\")
+						COUNT_SEQ(ptr, bk_count, dq_count)
+					}
+					/* Break for loop before next line increment when done */
+					if (!dq_count) break;
 				}
 			}
 
@@ -379,7 +420,7 @@ main (int argc, char **argv)
 		}
 	}
 
-	printf ("%s %s -%s %s \n", label, state_text (result), outbuff, perfstr);
+	printf ("%s %s -%s %s\n", label, state_text (result), outbuff, perfstr);
 	if (mult_resp) printf ("%s", mult_resp);
 
 	return result;


------------------------------------------------------------------------------
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.