[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(¤t_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(¤t_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(¤t_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(¤t_time, "String to read");
+ */
+
+
+ temp_state_key->_filename="var/generated";
+ time(¤t_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(¤t_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