[nagiosplug] Implemented writes to state file

Ton Voon tonvoon at users.sourceforge.net
Mon Jun 21 14:08:23 CEST 2010


 Module: nagiosplug
 Branch: ton/state
 Commit: f58aa8e66bbb4ecf23cf6add7efc574abb733d3a
 Author: Ton Voon <ton.voon at opsera.com>
   Date: Fri Jun 18 17:34:24 2010 +0100
    URL: http://nagiosplug.git.sf.net/git/gitweb.cgi?p=nagiosplug/nagiosplug;a=commit;h=f58aa8e

Implemented writes to state file

---

 lib/tests/test_utils.c |   64 ++++++++++++++++++++++++++++++++---
 lib/utils_base.c       |   87 +++++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 137 insertions(+), 14 deletions(-)

diff --git a/lib/tests/test_utils.c b/lib/tests/test_utils.c
index d7cdc33..6e04bfc 100644
--- a/lib/tests/test_utils.c
+++ b/lib/tests/test_utils.c
@@ -21,6 +21,9 @@
 
 #include "tap.h"
 
+#include <sys/types.h>
+#include <sys/stat.h>
+
 int
 main (int argc, char **argv)
 {
@@ -36,7 +39,7 @@ main (int argc, char **argv)
 	nagios_plugin *temp_nagios_plugin;
 	FILE    *temp_fp;
 
-	plan_tests(81+23);
+	plan_tests(134);
 
 	_get_nagios_plugin( &temp_nagios_plugin );
 	ok( temp_nagios_plugin==NULL, "nagios_plugin not initialised");
@@ -295,13 +298,11 @@ main (int argc, char **argv)
 	ok( !strcmp(temp_state_key->name, "Ahash"), "Got key name" );
 
 
-	printf("Filename=%s\n", temp_state_key->_filename);
 	np_enable_state("funnykeyname", 54);
 	temp_state_key = temp_nagios_plugin->state;
 	ok( !strcmp(temp_state_key->plugin_name, "check_test"), "Got plugin name" );
 	ok( !strcmp(temp_state_key->name, "funnykeyname"), "Got key name" );
 
-	printf("Filename=%s\n", temp_state_key->_filename);
 
 
 	ok( !strcmp(temp_state_key->_filename, "/usr/local/nagios/var/check_test/funnykeyname"), "Got internal filename" );
@@ -325,20 +326,71 @@ main (int argc, char **argv)
 	ok( temp_nagios_plugin->state->state_data!=NULL, "Got state data now" );
 	ok( temp_nagios_plugin->state->state_data->time==1234567890, "Got time" );
 	ok( !strcmp((char *)temp_nagios_plugin->state->state_data->data, "String to read"), "Data as expected" );
-	printf("state_data=%s|\n", temp_nagios_plugin->state->state_data->data);
 
+	temp_state_key->data_version=53;
+	temp_state_data = np_state_read(temp_state_key);
+	ok( temp_state_data==NULL, "Older data version gives NULL" );
+	temp_state_key->data_version=54;
 
 	temp_state_key->_filename="var/nonexistant";
 	temp_state_data = np_state_read(temp_state_key);
 	ok( temp_state_data==NULL, "Missing file gives NULL" );
 	ok( temp_nagios_plugin->state->state_data==NULL, "No state information" );
 
-	time(&current_time);
-	np_state_write_string(NULL, "New data");
+	temp_state_key->_filename="var/oldformat";
+	temp_state_data = np_state_read(temp_state_key);
+	ok( temp_state_data==NULL, "Old file format gives NULL" );
+
+	temp_state_key->_filename="var/baddate";
+	temp_state_data = np_state_read(temp_state_key);
+	ok( temp_state_data==NULL, "Bad date gives NULL" );
 
+	temp_state_key->_filename="var/missingdataline";
+	temp_state_data = np_state_read(temp_state_key);
+	ok( temp_state_data==NULL, "Missing data line gives NULL" );
+
+
+
+
+	unlink("var/generated");
+	temp_state_key->_filename="var/generated";
+	current_time=1234567890;
+	np_state_write_string(&current_time, "String to read");
+	ok(system("cmp var/generated var/statefile")==0, "Generated file same as expected");
+
+
+
+
+	unlink("var/generated_directory/statefile");
+	unlink("var/generated_directory");
+	temp_state_key->_filename="var/generated_directory/statefile";
+	current_time=1234567890;
+	np_state_write_string(&current_time, "String to read");
+	ok(system("cmp var/generated_directory/statefile var/statefile")==0, "Have created directory");
+
+	/* This test to check cannot write to dir - can't automate yet */
+	/*
+	unlink("var/generated_bad_dir");
+	mkdir("var/generated_bad_dir", S_IRUSR);
+	np_state_write_string(&current_time, "String to read");
+	*/
+
+
+	temp_state_key->_filename="var/generated";
+	time(&current_time);
+	np_state_write_string(NULL, "String to read");
 	temp_state_data = np_state_read(temp_state_key);
 	/* Check time is set to current_time */
+	ok(system("cmp var/generated var/statefile > /dev/null")!=0, "Generated file should be different this time");
+	ok(temp_nagios_plugin->state->state_data->time-current_time<=1, "Has time generated from current time");
+	
 
+	/* Don't know how to automatically test this. Need to be able to redefine die and catch the error */
+	/*
+	temp_state_key->_filename="/dev/do/not/expect/to/be/able/to/write";
+	np_state_write_string(NULL, "Bad file");
+	*/
+	
 
 	np_cleanup();
 	ok(temp_state_key==NULL, "temp_state_key cleared");
diff --git a/lib/utils_base.c b/lib/utils_base.c
index 8550577..5eaf57b 100644
--- a/lib/utils_base.c
+++ b/lib/utils_base.c
@@ -357,7 +357,6 @@ char *_np_state_generate_key() {
 void _cleanup_state_data() {
 	if (this_nagios_plugin->state->state_data!=NULL) {
 		np_free(this_nagios_plugin->state->state_data->data);
-		printf("***Setting\n");
 		np_free(this_nagios_plugin->state->state_data);
 	}
 }
@@ -399,6 +398,7 @@ void np_enable_state(char *keyname, int expected_data_version) {
 	this_state->name=keyname;
 	this_state->plugin_name=this_nagios_plugin->plugin_name;
 	this_state->data_version=expected_data_version;
+	this_state->state_data=NULL;
 
 	/* Calculate filename */
 	asprintf(&temp_filename, "%s/%s/%s", _np_state_calculate_location_prefix(), this_nagios_plugin->plugin_name, keyname);
@@ -433,6 +433,7 @@ state_data *np_state_read() {
 		if(this_state_data==NULL)
 			die(STATE_UNKNOWN, _("Cannot allocate memory for state data"));
 
+		this_state_data->data=NULL;
 		this_nagios_plugin->state->state_data = this_state_data;
 
 		rc = _np_state_read_file(statefile);
@@ -441,7 +442,6 @@ state_data *np_state_read() {
 	}
 
 	if(rc==FALSE) {
-		printf("Called\n");
 		_cleanup_state_data();
 	}
 
@@ -465,21 +465,17 @@ int _np_state_read_file(FILE *f) {
 	/* Note: This introduces a limit of 1024 bytes in the string data */
 	line = (char *) malloc(1024);
 
-	printf("Here\n");
 	while(!failure && (fgets(line,1024,f))!=NULL){
 		pos=strlen(line);
 		if(line[pos-1]=='\n') {
 			line[pos-1]='\0';
 		}
-		printf("Reading line |%s|\n", line);
 
 		if(line[0] == '#') continue;
 
 		switch(expected) {
 			case STATE_FILE_VERSION:
 				i=atoi(line);
-				//printf("line=|%d|, exp=|%d|\n", i, NP_STATE_FORMAT_VERSION);
-				//if(!strcmp(NP_STATE_FORMAT_VERSION, line)) {
 				if(i!=NP_STATE_FORMAT_VERSION)
 					failure++;
 				else
@@ -487,7 +483,6 @@ int _np_state_read_file(FILE *f) {
 				break;
 			case STATE_DATA_VERSION:
 				i=atoi(line);
-				printf("i=%d, exp=%d\n", i, this_nagios_plugin->state->data_version);
 				if(i != this_nagios_plugin->state->data_version)
 					failure++;
 				else
@@ -514,7 +509,6 @@ int _np_state_read_file(FILE *f) {
 	}
 
 	np_free(line);
-	printf("Returning status=%d\n", status);
 	return status;
 }
 
@@ -526,5 +520,82 @@ int _np_state_read_file(FILE *f) {
  * Will die with UNKNOWN if errors
  */
 void np_state_write_string(time_t *data_time, char *data_string) {
+	FILE *fp;
+	char *temp_file=NULL;
+	int fd=0, result=0;
+	time_t current_time;
+	size_t len;
+	char *directories=NULL;
+	char *p=NULL;
+
+	if(data_time==NULL)
+		time(&current_time);
+	else
+		current_time=*data_time;
+	
+	/* If file doesn't currently exist, create directories */
+	if(access(this_nagios_plugin->state->_filename,F_OK)!=0) {
+		asprintf(&directories, "%s", this_nagios_plugin->state->_filename);
+		if(directories==NULL)
+			die(STATE_UNKNOWN, _("Cannot malloc"));
+
+		for(p=directories+1; *p; p++) {
+			if(*p=='/') {
+				*p='\0';
+				if((access(directories,F_OK)!=0) && (mkdir(directories, S_IRWXU)!=0)) {
+					/* Can't free this! Otherwise error message is wrong! */
+					/* np_free(directories); */ 
+					die(STATE_UNKNOWN, _("Cannot create directory: %s"), directories);
+				}
+				*p='/';
+			}
+		}
+		np_free(directories);
+	}
+
+	asprintf(&temp_file,"%s.XXXXXX",this_nagios_plugin->state->_filename);
+	if(temp_file==NULL)
+		die(STATE_UNKNOWN, _("Cannot malloc temporary state file"));
+
+	if((fd=mkstemp(temp_file))==-1) {
+		np_free(temp_file);
+		die(STATE_UNKNOWN, _("Cannot create temporary filename"));
+	}
+
+	fp=(FILE *)fdopen(fd,"w");
+	if(fp==NULL) {
+		close(fd);
+		unlink(temp_file);
+		np_free(temp_file);
+		die(STATE_UNKNOWN, _("Unable to open temporary state file"));
+	}
+	
+	fprintf(fp,"# NP State file\n");
+	fprintf(fp,"%d\n",NP_STATE_FORMAT_VERSION);
+	fprintf(fp,"%d\n",this_nagios_plugin->state->data_version);
+	fprintf(fp,"%lu\n",current_time);
+	fprintf(fp,"%s\n",data_string);
+	
+	fchmod(fd, S_IRUSR | S_IWUSR | S_IRGRP);
+	
+	fflush(fp);
+
+	result=fclose(fp);
+
+	fsync(fd);
+
+	if(result!=0) {
+		unlink(temp_file);
+		np_free(temp_file);
+		die(STATE_UNKNOWN, _("Error writing temp file"));
+	}
+
+	if(rename(temp_file, this_nagios_plugin->state->_filename)!=0) {
+		unlink(temp_file);
+		np_free(temp_file);
+		die(STATE_UNKNOWN, _("Cannot rename state temp file"));
+	}
+
+	np_free(temp_file);
 }
 





More information about the Commits mailing list