From f58aa8e66bbb4ecf23cf6add7efc574abb733d3a Mon Sep 17 00:00:00 2001 From: Ton Voon Date: Fri, 18 Jun 2010 17:34:24 +0100 Subject: Implemented writes to state file 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 +#include + 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); } -- cgit v0.10-9-g596f