Back to index

nagios-plugins  1.4.16
Defines | Functions | Variables
utils_base.c File Reference
#include "common.h"
#include <stdarg.h>
#include "utils_base.h"
#include <fcntl.h>
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Defines

#define np_free(ptr)   { if(ptr) { free(ptr); ptr = NULL; } }

Functions

void np_init (char *plugin_name, int argc, char **argv)
void np_set_args (int argc, char **argv)
void np_cleanup ()
void _get_nagios_plugin (nagios_plugin **pointer)
void die (int result, const char *fmt,...)
void set_range_start (range *this, double value)
void set_range_end (range *this, double value)
rangeparse_range_string (char *str)
int _set_thresholds (thresholds **my_thresholds, char *warn_string, char *critical_string)
void set_thresholds (thresholds **my_thresholds, char *warn_string, char *critical_string)
void print_thresholds (const char *threshold_name, thresholds *my_threshold)
int check_range (double value, range *my_range)
int get_status (double value, thresholds *my_thresholds)
char * np_escaped_string (const char *string)
int np_check_if_root (void)
int np_warn_if_not_root (void)
char * np_extract_value (const char *varlist, const char *name, char sep)
char * _np_state_generate_key ()
void _cleanup_state_data ()
char * _np_state_calculate_location_prefix ()
void np_enable_state (char *keyname, int expected_data_version)
state_datanp_state_read ()
int _np_state_read_file (FILE *f)
void np_state_write_string (time_t data_time, char *data_string)

Variables

nagios_pluginthis_nagios_plugin = NULL

Define Documentation

#define np_free (   ptr)    { if(ptr) { free(ptr); ptr = NULL; } }

Definition at line 32 of file utils_base.c.


Function Documentation

Definition at line 399 of file utils_base.c.

Here is the caller graph for this function:

void _get_nagios_plugin ( nagios_plugin **  pointer)

Definition at line 77 of file utils_base.c.

                                                  {
       *pointer = this_nagios_plugin;
}

Definition at line 411 of file utils_base.c.

                                           {
       char *env_dir;

       env_dir = getenv("NAGIOS_PLUGIN_STATE_DIRECTORY");
       if(env_dir && env_dir[0] != '\0')
              return env_dir;
       return NP_STATE_DIR_PREFIX;
}

Here is the caller graph for this function:

Definition at line 371 of file utils_base.c.

                               {
       struct sha1_ctx ctx;
       int i;
       char **argv = this_nagios_plugin->argv;
       unsigned char result[20];
       char keyname[41];
       char *p=NULL;

       sha1_init_ctx(&ctx);
       
       for(i=0; i<this_nagios_plugin->argc; i++) {
              sha1_process_bytes(argv[i], strlen(argv[i]), &ctx);
       }

       sha1_finish_ctx(&ctx, &result);
       
       for (i=0; i<20; ++i) {
              sprintf(&keyname[2*i], "%02x", result[i]);
       }
       keyname[40]='\0';
       
       p = strdup(keyname);
       if(p==NULL) {
              die(STATE_UNKNOWN, _("Cannot execute strdup: %s"), strerror(errno));
       }
       return p;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int _np_state_read_file ( FILE *  f)

Definition at line 508 of file utils_base.c.

                                 {
       int status=FALSE;
       size_t pos;
       char *line;
       int i;
       int failure=0;
       time_t current_time, data_time;
       enum { STATE_FILE_VERSION, STATE_DATA_VERSION, STATE_DATA_TIME, STATE_DATA_TEXT, STATE_DATA_END } expected=STATE_FILE_VERSION;

       time(&current_time);

       /* Note: This introduces a limit of 1024 bytes in the string data */
       line = (char *) malloc(1024);
       if(line==NULL)
              die(STATE_UNKNOWN, _("Cannot allocate memory: %s"),
                  strerror(errno));

       while(!failure && (fgets(line,1024,f))!=NULL){
              pos=strlen(line);
              if(line[pos-1]=='\n') {
                     line[pos-1]='\0';
              }

              if(line[0] == '#') continue;

              switch(expected) {
                     case STATE_FILE_VERSION:
                            i=atoi(line);
                            if(i!=NP_STATE_FORMAT_VERSION)
                                   failure++;
                            else
                                   expected=STATE_DATA_VERSION;
                            break;
                     case STATE_DATA_VERSION:
                            i=atoi(line);
                            if(i != this_nagios_plugin->state->data_version)
                                   failure++;
                            else
                                   expected=STATE_DATA_TIME;
                            break;
                     case STATE_DATA_TIME:
                            /* If time > now, error */
                            data_time=strtoul(line,NULL,10);
                            if(data_time > current_time)
                                   failure++;
                            else {
                                   this_nagios_plugin->state->state_data->time = data_time;
                                   expected=STATE_DATA_TEXT;
                            }
                            break;
                     case STATE_DATA_TEXT:
                            this_nagios_plugin->state->state_data->data = strdup(line);
                            if(this_nagios_plugin->state->state_data->data==NULL)
                                   die(STATE_UNKNOWN, _("Cannot execute strdup: %s"), strerror(errno));
                            expected=STATE_DATA_END;
                            status=TRUE;
                            break;
                     case STATE_DATA_END:
                            ;
              }
       }

       np_free(line);
       return status;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int _set_thresholds ( thresholds **  my_thresholds,
char *  warn_string,
char *  critical_string 
)

Definition at line 153 of file utils_base.c.

{
       thresholds *temp_thresholds = NULL;

       if ((temp_thresholds = malloc(sizeof(thresholds))) == NULL)
              die(STATE_UNKNOWN, _("Cannot allocate memory: %s"),
                  strerror(errno));

       temp_thresholds->warning = NULL;
       temp_thresholds->critical = NULL;

       if (warn_string != NULL) {
              if ((temp_thresholds->warning = parse_range_string(warn_string)) == NULL) {
                     return NP_RANGE_UNPARSEABLE;
              }
       }
       if (critical_string != NULL) {
              if ((temp_thresholds->critical = parse_range_string(critical_string)) == NULL) {
                     return NP_RANGE_UNPARSEABLE;
              }
       }

       *my_thresholds = temp_thresholds;

       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int check_range ( double  value,
range my_range 
)

Definition at line 215 of file utils_base.c.

{
       int no = FALSE;
       int yes = TRUE;

       if (my_range->alert_on == INSIDE) {
              no = TRUE;
              yes = FALSE;
       }

       if (my_range->end_infinity == FALSE && my_range->start_infinity == FALSE) {
              if ((my_range->start <= value) && (value <= my_range->end)) {
                     return no;
              } else {
                     return yes;
              }
       } else if (my_range->start_infinity == FALSE && my_range->end_infinity == TRUE) {
              if (my_range->start <= value) {
                     return no;
              } else {
                     return yes;
              }
       } else if (my_range->start_infinity == TRUE && my_range->end_infinity == FALSE) {
              if (value <= my_range->end) {
                     return no;
              } else {
                     return yes;
              }
       } else {
              return no;
       }
}

Here is the caller graph for this function:

void die ( int  result,
const char *  fmt,
  ... 
)

Definition at line 82 of file utils_base.c.

{
       va_list ap;
       va_start (ap, fmt);
       vprintf (fmt, ap);
       va_end (ap);
       if(this_nagios_plugin!=NULL) {
              np_cleanup();
       }
       exit (result);
}

Here is the call graph for this function:

int get_status ( double  value,
thresholds my_thresholds 
)

Definition at line 250 of file utils_base.c.

{
       if (my_thresholds->critical != NULL) {
              if (check_range(value, my_thresholds->critical) == TRUE) {
                     return STATE_CRITICAL;
              }
       }
       if (my_thresholds->warning != NULL) {
              if (check_range(value, my_thresholds->warning) == TRUE) {
                     return STATE_WARNING;
              }
       }
       return STATE_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int np_check_if_root ( void  )

Definition at line 295 of file utils_base.c.

{ return (geteuid() == 0); }

Here is the caller graph for this function:

void np_cleanup ( )
void np_enable_state ( char *  keyname,
int  expected_data_version 
)

Definition at line 425 of file utils_base.c.

                                                               {
       state_key *this_state = NULL;
       char *temp_filename = NULL;
       char *temp_keyname = NULL;
       char *p=NULL;

       if(this_nagios_plugin==NULL)
              die(STATE_UNKNOWN, _("This requires np_init to be called"));

       this_state = (state_key *) malloc(sizeof(state_key));
       if(this_state==NULL)
              die(STATE_UNKNOWN, _("Cannot allocate memory: %s"),
                  strerror(errno));

       if(keyname==NULL) {
              temp_keyname = _np_state_generate_key();
       } else {
              temp_keyname = strdup(keyname);
              if(temp_keyname==NULL)
                     die(STATE_UNKNOWN, _("Cannot execute strdup: %s"), strerror(errno));
       }
       /* Die if invalid characters used for keyname */
       p = temp_keyname;
       while(*p!='\0') {
              if(! (isalnum(*p) || *p == '_')) {
                     die(STATE_UNKNOWN, _("Invalid character for keyname - only alphanumerics or '_'"));
              }
              p++;
       }
       this_state->name=temp_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, this_state->name);
       this_state->_filename=temp_filename;

       this_nagios_plugin->state = this_state;
}

Here is the call graph for this function:

Here is the caller graph for this function:

char* np_escaped_string ( const char *  string)

Definition at line 265 of file utils_base.c.

                                             {
       char *data;
       int i, j=0;
       data = strdup(string);
       for (i=0; data[i]; i++) {
              if (data[i] == '\\') {
                     switch(data[++i]) {
                            case 'n':
                                   data[j++] = '\n';
                                   break;
                            case 'r':
                                   data[j++] = '\r';
                                   break;
                            case 't':
                                   data[j++] = '\t';
                                   break;
                            case '\\':
                                   data[j++] = '\\';
                                   break;
                            default:
                                   data[j++] = data[i];
                     }
              } else {
                     data[j++] = data[i];
              }
       }
       data[j] = '\0';
       return data;
}

Here is the caller graph for this function:

char* np_extract_value ( const char *  varlist,
const char *  name,
char  sep 
)

Definition at line 316 of file utils_base.c.

                                                                        {
       char *tmp=NULL, *value=NULL;
       int i;

       while (1) {
              /* Strip any leading space */
              for (varlist; isspace(varlist[0]); varlist++);

              if (strncmp(name, varlist, strlen(name)) == 0) {
                     varlist += strlen(name);
                     /* strip trailing spaces */
                     for (varlist; isspace(varlist[0]); varlist++);

                     if (varlist[0] == '=') {
                            /* We matched the key, go past the = sign */
                            varlist++;
                            /* strip leading spaces */
                            for (varlist; isspace(varlist[0]); varlist++);

                            if (tmp = index(varlist, sep)) {
                                   /* Value is delimited by a comma */
                                   if (tmp-varlist == 0) continue;
                                   value = (char *)malloc(tmp-varlist+1);
                                   strncpy(value, varlist, tmp-varlist);
                                   value[tmp-varlist] = '\0';
                            } else {
                                   /* Value is delimited by a \0 */
                                   if (strlen(varlist) == 0) continue;
                                   value = (char *)malloc(strlen(varlist) + 1);
                                   strncpy(value, varlist, strlen(varlist));
                                   value[strlen(varlist)] = '\0';
                            }
                            break;
                     }
              }
              if (tmp = index(varlist, sep)) {
                     /* More keys, keep going... */
                     varlist = tmp + 1;
              } else {
                     /* We're done */
                     break;
              }
       }

       /* Clean-up trailing spaces/newlines */
       if (value) for (i=strlen(value)-1; isspace(value[i]); i--) value[i] = '\0';

       return value;
}
void np_init ( char *  plugin_name,
int  argc,
char **  argv 
)

Definition at line 36 of file utils_base.c.

                                                         {
       if (this_nagios_plugin==NULL) {
              this_nagios_plugin = malloc(sizeof(nagios_plugin));
              if (this_nagios_plugin==NULL) {
                     die(STATE_UNKNOWN, _("Cannot allocate memory: %s"),
                         strerror(errno));
              }
              this_nagios_plugin->plugin_name = strdup(plugin_name);
              if (this_nagios_plugin->plugin_name==NULL)
                     die(STATE_UNKNOWN, _("Cannot execute strdup: %s"), strerror(errno));
              this_nagios_plugin->argc = argc;
              this_nagios_plugin->argv = argv;
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void np_set_args ( int  argc,
char **  argv 
)

Definition at line 51 of file utils_base.c.

                                          {
       if (this_nagios_plugin==NULL)
              die(STATE_UNKNOWN, _("This requires np_init to be called"));

       this_nagios_plugin->argc = argc;
       this_nagios_plugin->argv = argv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 473 of file utils_base.c.

                            {
       state_data *this_state_data=NULL;
       FILE *statefile;
       int rc = FALSE;

       if(this_nagios_plugin==NULL)
              die(STATE_UNKNOWN, _("This requires np_init to be called"));

       /* Open file. If this fails, no previous state found */
       statefile = fopen( this_nagios_plugin->state->_filename, "r" );
       if(statefile!=NULL) {

              this_state_data = (state_data *) malloc(sizeof(state_data));
              if(this_state_data==NULL)
                     die(STATE_UNKNOWN, _("Cannot allocate memory: %s"),
                         strerror(errno));

              this_state_data->data=NULL;
              this_nagios_plugin->state->state_data = this_state_data;

              rc = _np_state_read_file(statefile);

              fclose(statefile);
       }

       if(rc==FALSE) {
              _cleanup_state_data();
       }

       return this_nagios_plugin->state->state_data;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void np_state_write_string ( time_t  data_time,
char *  data_string 
)

Definition at line 581 of file utils_base.c.

                                                                {
       FILE *fp;
       char *temp_file=NULL;
       int fd=0, result=0;
       time_t current_time;
       char *directories=NULL;
       char *p=NULL;

       if(data_time==0)
              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 allocate memory: %s"),
                         strerror(errno));

              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 allocate memory: %s"),
                  strerror(errno));

       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);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int np_warn_if_not_root ( void  )

Definition at line 297 of file utils_base.c.

                              {
       int status = np_check_if_root();
       if(!status) {
              printf(_("Warning: "));
              printf(_("This plugin must be either run as root or setuid root.\n"));
              printf(_("To run as root, you can use a tool like sudo.\n"));
              printf(_("To set the setuid permissions, use the command:\n"));
              /* XXX could we use something like progname? */
              printf("\tchmod u+s yourpluginfile\n");
       }
       return status;
}

Here is the call graph for this function:

Here is the caller graph for this function:

range* parse_range_string ( char *  str)

Definition at line 105 of file utils_base.c.

                                {
       range *temp_range;
       double start;
       double end;
       char *end_str;

       temp_range = (range *) malloc(sizeof(range));

       /* Set defaults */
       temp_range->start = 0;
       temp_range->start_infinity = FALSE;
       temp_range->end = 0;
       temp_range->end_infinity = TRUE;
       temp_range->alert_on = OUTSIDE;

       if (str[0] == '@') {
              temp_range->alert_on = INSIDE;
              str++;
       }

       end_str = index(str, ':');
       if (end_str != NULL) {
              if (str[0] == '~') {
                     temp_range->start_infinity = TRUE;
              } else {
                     start = strtod(str, NULL);  /* Will stop at the ':' */
                     set_range_start(temp_range, start);
              }
              end_str++;           /* Move past the ':' */
       } else {
              end_str = str;
       }
       end = strtod(end_str, NULL);
       if (strcmp(end_str, "") != 0) {
              set_range_end(temp_range, end);
       }

       if (temp_range->start_infinity == TRUE ||
              temp_range->end_infinity == TRUE ||
              temp_range->start <= temp_range->end) {
              return temp_range;
       }
       free(temp_range);
       return NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void print_thresholds ( const char *  threshold_name,
thresholds my_threshold 
)

Definition at line 194 of file utils_base.c.

                                                                            {
       printf("%s - ", threshold_name);
       if (! my_threshold) {
              printf("Threshold not set");
       } else {
              if (my_threshold->warning) {
                     printf("Warning: start=%g end=%g; ", my_threshold->warning->start, my_threshold->warning->end);
              } else {
                     printf("Warning not set; ");
              }
              if (my_threshold->critical) {
                     printf("Critical: start=%g end=%g", my_threshold->critical->start, my_threshold->critical->end);
              } else {
                     printf("Critical not set");
              }
       }
       printf("\n");
}

Here is the caller graph for this function:

void set_range_end ( range this,
double  value 
)

Definition at line 99 of file utils_base.c.

                                               {
       this->end = value;
       this->end_infinity = FALSE;
}

Here is the caller graph for this function:

void set_range_start ( range this,
double  value 
)

Definition at line 94 of file utils_base.c.

                                                 {
       this->start = value;
       this->start_infinity = FALSE;
}

Here is the caller graph for this function:

void set_thresholds ( thresholds **  my_thresholds,
char *  warn_string,
char *  critical_string 
)

Definition at line 181 of file utils_base.c.

{
       switch (_set_thresholds(my_thresholds, warn_string, critical_string)) {
       case 0:
              return;
       case NP_RANGE_UNPARSEABLE:
              die(STATE_UNKNOWN, _("Range format incorrect"));
       case NP_WARN_WITHIN_CRIT:
              die(STATE_UNKNOWN, _("Warning level is a subset of critical and will not be alerted"));
              break;
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

Definition at line 34 of file utils_base.c.