[icinga-checkins] icinga.org: icinga-nsca/mfriedrich/fixes: * add config directive to submit directly to checkresults directory ( Mike Lindsey) #2100, Support multi-line check output with 4000 character limit (Mike Lindsey) #2101

git at icinga.org git at icinga.org
Wed Nov 23 18:23:32 CET 2011


Module: icinga-nsca
Branch: mfriedrich/fixes
Commit: b6747a7a8c2c017e359094921f5cbca9444d8550
URL:    https://git.icinga.org/?p=icinga-nsca.git;a=commit;h=b6747a7a8c2c017e359094921f5cbca9444d8550

Author: Michael Friedrich <michael.friedrich at univie.ac.at>
Date:   Wed Nov 23 18:23:02 2011 +0100

* add config directive to submit directly to checkresults directory (Mike Lindsey) #2100, Support multi-line check output with 4000 character limit (Mike Lindsey) #2101

refs #2100
refs #2101

---

 AUTHORS         |    1 +
 Changelog       |   23 ++++++++++++++---
 src/nsca.c      |   74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 src/send_nsca.c |   31 +++++++++++++++++------
 src/utils.c     |   32 +++++++++++++++++++++++
 5 files changed, 148 insertions(+), 13 deletions(-)

diff --git a/AUTHORS b/AUTHORS
index 25831da..8c121fa 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,2 +1,3 @@
 Ethan Galstad
+Mike Lindsey
 Florian Obser
diff --git a/Changelog b/Changelog
index 821cc54..16c6a46 100644
--- a/Changelog
+++ b/Changelog
@@ -1,14 +1,29 @@
-**************
-NSCA Changelog
-**************
+*********************
+Icinga NSCA Changelog
+*********************
 
 XXX - XX/XX/XXXX
 
 ENHANCEMENTS
-- add IPv6 support
+* add IPv6 support
+* add config directive to submit directly to checkresults directory (Mike Lindsey) #2100
+	** --with-checkresult-dir=<path> for configure
+* Support multi-line check output with 4000 character limit (Mike Lindsey) #2101
 
 FIXES
 
+CHANGES
+
+* nsca.cfg
+	** check_result_path
+* configure
+	** --with-checkresult-dir=<path>
+
+
+***********************
+Archived NRPE Changelog
+***********************
+
 
 2.8 - ??/??/????
 ----------------
diff --git a/src/nsca.c b/src/nsca.c
index 2bf4a68..4712dbf 100644
--- a/src/nsca.c
+++ b/src/nsca.c
@@ -1186,16 +1186,88 @@ static void handle_connection_read(int sock, void *data) {
 	 * use poll() - which fails on a pipe with any data, so it would cause us to
 	 * only ever write one command at a time into the pipe.
 	 */
-	write_check_result(host_name, svc_description, return_code, plugin_output, time(NULL));
+	if (check_result_path == NULL) {
+		write_check_result(host_name, svc_description, return_code, plugin_output, time(NULL));
+	} else {
+		write_checkresult_file(host_name, svc_description, return_code, plugin_output, time(NULL));
+	}
 
 	return;
 }
 
+/* writes service / host check results to the Nagios checkresult directory */
+static int write_checkresult_file(char *host_name, char *svc_description, int return_code, char *plugin_output, time_t check_time) {
+	mode_t new_umask = 077;
+	mode_t old_umask;
+	time_t current_time;
+	char *output_file = NULL;
+	int checkresult_file_fd = -1;
+	char *checkresult_file = NULL;
+	char *checkresult_ok_file = NULL;
+	FILE *checkresult_file_fp = NULL;
+	FILE *checkresult_ok_file_fp = NULL;
+
+	if (debug == TRUE)
+		syslog(LOG_ERR, "Attempting to write checkresult file");
+
+	/* change and store umask */
+	old_umask = umask(new_umask);
+
+	/* create safe checkresult file */
+	asprintf(&checkresult_file, "%s/cXXXXXX", check_result_path);
+	/* FIXME free temp buffers */
+
+	checkresult_file_fd = mkstemp(checkresult_file);
+	if (checkresult_file_fd > 0) {
+		checkresult_file_fp = fdopen(checkresult_file_fd, "w");
+	} else {
+		syslog(LOG_ERR, "Unable to open and write checkresult file '%s', failing back to PIPE", checkresult_file);
+		return write_check_result(host_name, svc_description, return_code, plugin_output, check_time);
+	}
+
+	if (debug == TRUE)
+		syslog(LOG_ERR, "checkresult file '%s' open for write.", checkresult_file);
+
+	time(&current_time);
+	fprintf(checkresult_file_fp, "### NSCA Passive Check Result ###\n");
+	fprintf(checkresult_file_fp, "# Time: %s", ctime(&current_time));
+	fprintf(checkresult_file_fp, "file_time=%d\n\n", current_time);
+	fprintf(checkresult_file_fp, "### %s Check Result ###\n", (svc_description == "") ? "Host" : "Service");
+	fprintf(checkresult_file_fp, "host_name=%s\n", host_name);
+	if (strcmp(svc_description, ""))
+		fprintf(checkresult_file_fp, "service_description=%s\n", svc_description);
+	fprintf(checkresult_file_fp, "check_type=1\n");
+	fprintf(checkresult_file_fp, "scheduled_check=0\n");
+	fprintf(checkresult_file_fp, "reschedule_check=0\n");
+	/* We have no latency data at this point. */
+	fprintf(checkresult_file_fp, "latency=0\n");
+	fprintf(checkresult_file_fp, "start_time=%lu.%lu\n", check_time, 0L);
+	fprintf(checkresult_file_fp, "finish_time=%lu.%lu\n", check_time, 0L);
+	fprintf(checkresult_file_fp, "return_code=%d\n", return_code);
+	/* newlines in output are already escaped */
+	fprintf(checkresult_file_fp, "output=%s\n", (plugin_output == NULL) ? "" : plugin_output);
+	fprintf(checkresult_file_fp, "\n");
+
+	fclose(checkresult_file_fp);
+	/* create and close ok file */
+	asprintf(&checkresult_ok_file, "%s.ok", checkresult_file);
+	syslog(LOG_DEBUG, "checkresult completion file '%s' open.", checkresult_ok_file);
+	checkresult_ok_file_fp = fopen(checkresult_ok_file, "w");
+	fclose(checkresult_ok_file_fp);
+	/* reset umask */
+	umask(old_umask);
+
+	return OK;
+}
+
 
 
 /* writes service/host check results to the Nagios command file */
 static int write_check_result(char *host_name, char *svc_description, int return_code, char *plugin_output, time_t check_time) {
 
+	if (debug == TRUE)
+		syslog(LOG_ERR, "Attempting to write to nagios command pipe");
+
 	if (aggregate_writes == FALSE) {
 		if (open_command_file() == ERROR)
 			return ERROR;
diff --git a/src/send_nsca.c b/src/send_nsca.c
index 7a23ef6..39786d4 100644
--- a/src/send_nsca.c
+++ b/src/send_nsca.c
@@ -27,6 +27,7 @@ char server_name[MAX_HOST_ADDRESS_LENGTH];
 char password[MAX_INPUT_BUFFER] = "";
 char config_file[MAX_INPUT_BUFFER] = "send_nsca.cfg";
 char delimiter[2] = "\t";
+char block_delimiter[2] = BLOCK_DELIMITER;
 
 char received_iv[TRANSMITTED_IV_SIZE];
 
@@ -61,6 +62,7 @@ int main(int argc, char **argv) {
 	int result;
 	data_packet send_packet;
 	int bytes_to_send;
+	char input[MAX_INPUT_BUFFER];
 	char input_buffer[MAX_INPUT_BUFFER];
 	char *temp_ptr;
 	char host_name[MAX_HOSTNAME_LENGTH];
@@ -69,7 +71,7 @@ int main(int argc, char **argv) {
 	int total_packets = 0;
 	int16_t return_code;
 	u_int32_t calculated_crc32;
-	char *ptr1, *ptr2, *ptr3, *ptr4;
+	char *inputptr, *ptr1, *ptr2, *ptr3, *ptr4;
 
 
 	/* process command-line arguments */
@@ -114,7 +116,9 @@ int main(int argc, char **argv) {
 		printf("Service Checks:\n");
 		printf("<host_name>[tab]<svc_description>[tab]<return_code>[tab]<plugin_output>[newline]\n\n");
 		printf("Host Checks:\n");
-		printf("<host_name>[tab]<return_code>[tab]<plugin_output>[newline]\n");
+		printf("<host_name>[tab]<return_code>[tab]<plugin_output>[newline]\n\n");
+		printf("When submitting multiple simultaneous results, separate each set with the ETB\n");
+		printf("character (^W or 0x17)\n");
 		printf("\n");
 	}
 
@@ -186,10 +190,21 @@ int main(int argc, char **argv) {
 	/**** WE'RE CONNECTED AND READY TO SEND ****/
 
 	/* read all data from STDIN until there isn't anymore */
-	while (fgets(input_buffer, sizeof(input_buffer) - 1, stdin)) {
-
-		if (feof(stdin))
+	while (!feof(stdin)) {
+		int c = getc(stdin);
+		if (c == -1) {
 			break;
+		}
+		int pos = 0;
+		while (c != 23) {
+			if (c == -1) { // in case we don't terminate properly, or are in single-input mode.
+				break;
+			}
+			input_buffer[pos] = c;
+			c = getc(stdin);
+			pos++;
+		}
+		input_buffer[pos] = 0;
 
 		strip(input_buffer);
 
@@ -212,19 +227,19 @@ int main(int argc, char **argv) {
 			continue;
 
 		/* get the plugin output - if NULL, this is a host check result */
-		ptr4 = strtok(NULL, "\n");
+		ptr4 = strtok(NULL, "\x0");
 
 		strncpy(host_name, ptr1, sizeof(host_name) - 1);
 		host_name[sizeof(host_name) - 1] = '\x0';
 		if (ptr4 == NULL) {
 			strcpy(svc_description, "");
 			return_code = atoi(ptr2);
-			if (plugin_output[strlen(plugin_output) - 1] == '\n')
-				plugin_output[strlen(plugin_output) - 1] = '\x0';
+			ptr3 = escape_newlines(ptr3);
 			strncpy(plugin_output, ptr3, sizeof(plugin_output) - 1);
 		} else {
 			strncpy(svc_description, ptr2, sizeof(svc_description) - 1);
 			return_code = atoi(ptr3);
+			ptr4 = escape_newlines(ptr4);
 			strncpy(plugin_output, ptr4, sizeof(plugin_output) - 1);
 		}
 		svc_description[sizeof(svc_description) - 1] = '\x0';
diff --git a/src/utils.c b/src/utils.c
index f72e2a9..6140fa4 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -40,7 +40,39 @@ static unsigned long crc32_table[256];
 static volatile sig_atomic_t mcrypt_initialized = FALSE;
 #endif
 
+/* escapes newlines in a string, snagged from nagios-3.0.6/base/utils.c */
+char *escape_newlines(char *rawbuf) {
+	char *newbuf = NULL;
+	register int x, y;
 
+	if (rawbuf == NULL)
+		return NULL;
+
+	/* allocate enough memory to escape all chars if necessary */
+	if ((newbuf = malloc((strlen(rawbuf) * 2) + 1)) == NULL)
+		return NULL;
+
+	for (x = 0, y = 0; rawbuf[x] != (char)'\x0'; x++) {
+
+		/* escape backslashes */
+		if (rawbuf[x] == '\\') {
+			newbuf[y++] = '\\';
+			newbuf[y++] = '\\';
+		}
+
+		/* escape newlines */
+		else if (rawbuf[x] == '\n') {
+			newbuf[y++] = '\\';
+			newbuf[y++] = 'n';
+		}
+
+		else
+			newbuf[y++] = rawbuf[x];
+	}
+	newbuf[y] = '\x0';
+
+	return newbuf;
+}
 
 
 /* build the crc table - must be called before calculating the crc value */





More information about the icinga-checkins mailing list