Logo Search packages:      
Sourcecode: nagcon version File versions  Download package

pl.cpp

/*
 * Copyright (C) 2006 Folkert van Heusden <folkert@vanheusden.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#include <stdio.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
#include <errno.h>
#include <sys/select.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <ctype.h>

extern "C" {
#include "error.h"
}
#include "utils.h"
#include "br.h"
#include "pl.h"

static struct v2_0_config v2_0_config_elements[] = {
      {"acknowledgement_type",      STATS_OFFSET(acknowledgement_type), VARTYPE_INT}, 
      {"active_checks_enabled",     STATS_OFFSET(active_checks_enabled),      VARTYPE_INT}, 
      {"author",              STATS_OFFSET(author),               VARTYPE_PCHAR},
      {"check_command",       STATS_OFFSET(check_command),        VARTYPE_PCHAR}, 
      {"check_execution_time",      STATS_OFFSET(check_execution_time), VARTYPE_DOUBLE}, 
      {"check_interval",            STATS_OFFSET(check_interval),       VARTYPE_DOUBLE},
      {"check_latency",       STATS_OFFSET(check_latency),        VARTYPE_DOUBLE}, 
      {"check_options",       STATS_OFFSET(check_options),        VARTYPE_INT},
      {"check_period",        STATS_OFFSET(check_period),         VARTYPE_PCHAR},
      {"check_type",                STATS_OFFSET(check_type),           VARTYPE_INT}, 
      {"comment",             STATS_OFFSET(comment),              VARTYPE_PCHAR},
      {"comment_data",        STATS_OFFSET(comment_data),         VARTYPE_PCHAR},
      {"comment_id",                STATS_OFFSET(comment_id),           VARTYPE_INT},
      {"current_attempt",           STATS_OFFSET(current_attempt),            VARTYPE_INT}, 
      {"current_event_id",          STATS_OFFSET(current_event_id),           VARTYPE_INT},
      {"current_notification_id",   STATS_OFFSET(current_notification_id),    VARTYPE_INT},
      {"current_notification_number",     STATS_OFFSET(current_notification_number),      VARTYPE_DOUBLE}, 
      {"current_problem_id",        STATS_OFFSET(current_problem_id),   VARTYPE_INT},
      {"current_state",       STATS_OFFSET(current_state),        VARTYPE_INT}, 
      {"downtime_id",               STATS_OFFSET(downtime_id),          VARTYPE_INT},
      {"duration",                  STATS_OFFSET(duration),             VARTYPE_INT},
      {"end_time",                  STATS_OFFSET(end_time),             VARTYPE_TIMET},
      {"entry_time",                STATS_OFFSET(entry_time),           VARTYPE_TIMET},
      {"entry_type",                STATS_OFFSET(entry_type),           VARTYPE_INT},
      {"event_handler",       STATS_OFFSET(event_handler),        VARTYPE_INT}, 
      {"event_handler_enabled",     STATS_OFFSET(event_handler_enabled),      VARTYPE_INT}, 
      {"expire_time",               STATS_OFFSET(expire_time),          VARTYPE_TIMET},
      {"expires",             STATS_OFFSET(expires),              VARTYPE_INT},
      {"failure_prediction_enabled",      STATS_OFFSET(failure_prediction_enabled), VARTYPE_INT}, 
      {"fixed",               STATS_OFFSET(fixed),                VARTYPE_INT},
      {"flap_detection_enabled",    STATS_OFFSET(flap_detection_enabled),     VARTYPE_INT}, 
      {"has_been_checked",          STATS_OFFSET(has_been_checked),           VARTYPE_INT}, 
      {"host_name",                 STATS_OFFSET(host_name),            VARTYPE_PCHAR}, 
      {"host_notification_period",  STATS_OFFSET(host_notification_period),   VARTYPE_PCHAR},
      {"is_flapping",               STATS_OFFSET(is_flapping),          VARTYPE_INT}, 
      {"last_check",                STATS_OFFSET(last_check),           VARTYPE_TIMET}, 
      {"last_event_id",       STATS_OFFSET(last_event_id),        VARTYPE_INT},
      {"last_hard_state",           STATS_OFFSET(last_hard_state),            VARTYPE_INT}, 
      {"last_hard_state_change",    STATS_OFFSET(last_hard_state_change),     VARTYPE_INT}, 
      {"last_notification",         STATS_OFFSET(last_notification),    VARTYPE_INT}, 
      {"last_problem_id",           STATS_OFFSET(last_problem_id),            VARTYPE_INT},
      {"last_state_change",         STATS_OFFSET(last_state_change),    VARTYPE_TIMET}, 
      {"last_time_critical",        STATS_OFFSET(last_time_critical),   VARTYPE_INT}, 
      {"last_time_down",            STATS_OFFSET(last_time_down),       VARTYPE_INT}, 
      {"last_time_ok",        STATS_OFFSET(last_time_ok),         VARTYPE_INT}, 
      {"last_time_unknown",         STATS_OFFSET(last_time_unknown),    VARTYPE_INT}, 
      {"last_time_unreachable",     STATS_OFFSET(last_time_unreachable),      VARTYPE_INT}, 
      {"last_time_up",        STATS_OFFSET(last_time_up),         VARTYPE_INT}, 
      {"last_time_warning",         STATS_OFFSET(last_time_warning),    VARTYPE_INT}, 
      {"last_update",               STATS_OFFSET(last_update),          VARTYPE_TIMET}, 
      {"long_plugin_output",        STATS_OFFSET(long_plugin_output),   VARTYPE_PCHAR},
      {"max_attempts",        STATS_OFFSET(max_attempts),         VARTYPE_INT}, 
      {"modified_attributes",       STATS_OFFSET(modified_attributes),  VARTYPE_INT}, 
      {"next_check",                STATS_OFFSET(next_check),           VARTYPE_TIMET}, 
      {"next_comment_id",           STATS_OFFSET(next_comment_id),            VARTYPE_INT},
      {"next_notification",         STATS_OFFSET(next_notification),    VARTYPE_INT}, 
      {"no_more_notifications",     STATS_OFFSET(no_more_notifications),      VARTYPE_INT}, 
      {"notification_period",       STATS_OFFSET(notification_period),  VARTYPE_PCHAR},
      {"notifications_enabled",     STATS_OFFSET(notifications_enabled),      VARTYPE_INT}, 
      {"obsess_over_host",          STATS_OFFSET(obsess_over_host),           VARTYPE_INT},
      {"obsess_over_service",       STATS_OFFSET(obsess_over_service),  VARTYPE_INT}, 
      {"passive_checks_enabled",    STATS_OFFSET(passive_checks_enabled),     VARTYPE_INT}, 
      {"percent_state_change",      STATS_OFFSET(percent_state_change), VARTYPE_DOUBLE}, 
      {"performance_data",          STATS_OFFSET(performance_data),           VARTYPE_PCHAR}, 
      {"persistent",                STATS_OFFSET(persistent),           VARTYPE_INT},
      {"plugin_output",       STATS_OFFSET(plugin_output),        VARTYPE_PCHAR}, 
      {"problem_has_been_acknowledged",   STATS_OFFSET(problem_has_been_acknowledged),    VARTYPE_INT}, 
      {"process_performance_data",  STATS_OFFSET(process_performance_data),   VARTYPE_INT}, 
      {"retry_interval",            STATS_OFFSET(retry_interval),       VARTYPE_DOUBLE},
      {"scheduled_downtime_depth",  STATS_OFFSET(scheduled_downtime_depth),   VARTYPE_DOUBLE}, 
      {"service_description",       STATS_OFFSET(service_description),  VARTYPE_PCHAR}, 
      {"should_be_scheduled",       STATS_OFFSET(should_be_scheduled),  VARTYPE_INT}, 
      {"source",              STATS_OFFSET(source),               VARTYPE_INT},
      {"start_time",                STATS_OFFSET(start_time),           VARTYPE_TIMET},
      {"state_type",                STATS_OFFSET(state_type),           VARTYPE_INT}, 
      {"triggered_by",        STATS_OFFSET(triggered_by),         VARTYPE_INT},
      {"type",                STATS_OFFSET(type),                 VARTYPE_INT}
};

/*
   service {
   host_name=ap
   service_description=HTTP
   modified_attributes=0
   check_command=check_tcp!80
   event_handler=
   has_been_checked=1
   should_be_scheduled=1
   check_execution_time=0.009
   check_latency=0.712
   current_state=0
   last_hard_state=0
   current_attempt=1
   max_attempts=3
   state_type=1
   last_state_change=1128634047
   last_hard_state_change=1128633828
   last_time_ok=1129101510
   last_time_warning=0
   last_time_unknown=1128633828
   last_time_critical=1126954624
   plugin_output=TCP OK - 0.001 second response time on port 80
   performance_data=time=0.001121s;0.000000;0.000000;0.000000;10.000000
   last_check=1129101510
   next_check=1129101630
   check_type=0
   current_notification_number=0
   last_notification=0
   next_notification=0
   no_more_notifications=0
   notifications_enabled=1
   active_checks_enabled=1
   passive_checks_enabled=1
   event_handler_enabled=1
   problem_has_been_acknowledged=0
   acknowledgement_type=0
   flap_detection_enabled=1
   failure_prediction_enabled=1
   process_performance_data=1
   obsess_over_service=1
   last_update=1129101556
   is_flapping=0
   percent_state_change=0.00
   scheduled_downtime_depth=0
   }

   host {
   host_name=ap
   modified_attributes=0
   check_command=check-host-alive
   event_handler=
   has_been_checked=1
   should_be_scheduled=0
   check_execution_time=0.012
   check_latency=0.000
   current_state=0
   last_hard_state=0
   check_type=0
   plugin_output=PING OK - Packet loss = 0%, RTA = 1.54 ms
   performance_data=
   last_check=1128863442
   next_check=0
   current_attempt=1
   max_attempts=10
   state_type=1
   last_state_change=1128634057
   last_hard_state_change=1128634057
   last_time_up=1128863442
   last_time_down=1128633868
   last_time_unreachable=0
   last_notification=1128634057
next_notification=0
no_more_notifications=0
current_notification_number=0
notifications_enabled=1
problem_has_been_acknowledged=0
acknowledgement_type=0
active_checks_enabled=1
passive_checks_enabled=1
event_handler_enabled=1
flap_detection_enabled=1
failure_prediction_enabled=1
process_performance_data=1
obsess_over_host=1
last_update=1129101556
is_flapping=0
percent_state_change=0.00
scheduled_downtime_depth=0
}
*/

int v2_0_find_entry_type(char *field_name)
{
      int left = 0;
      int right = (sizeof(v2_0_config_elements) / sizeof(struct v2_0_config)) - 1;

      while(left <= right)
      {
            int mid = (left + right) / 2;
            int compare = strcmp(field_name, v2_0_config_elements[mid].str);

            if (compare > 0)
                  left = mid + 1;
            else if (compare < 0)
                  right = mid - 1;
            else
                  return mid;
      }

      return -1;
}

void parse_2_0_statuslog(int fd, struct stats **pstats, int *n_stats)
{
      int n_alloc = 0;
      int type = TYPE_IGNORE;

      /* start up buffered reader */
      buffered_reader bf(fd);

      *pstats = NULL;
      *n_stats = 0;

      for(;;)
      {
            char *line = bf.read_line();
            if (!line)
                  break;

            if (strchr(line, '{'))
            {
                  /* init */
                  type = TYPE_IGNORE;

                  if (*n_stats == n_alloc)
                  {
                        if (n_alloc)
                              n_alloc *= 2;
                        else
                              n_alloc = 128;

                        *pstats = (struct stats *)myrealloc(*pstats, n_alloc * sizeof(struct stats), "stats array");
                        if (!*pstats)
                              error_exit("Error allocating memory");

                        memset(&(*pstats)[*n_stats], 0x00, sizeof(struct stats) * (n_alloc - *n_stats));
                  }
                  else
                  {
                        memset(&(*pstats)[*n_stats], 0x00, sizeof(struct stats));
                  }


                  if (strncmp(line, "host", 4) == 0)
                  {
                        type = TYPE_HOST;
                  }
                  else if (strncmp(line, "service", 7) == 0)
                  {
                        type = TYPE_SERVICE;
                  }
                  else
                  {
                        type = TYPE_IGNORE;
                  }
            }
            else if (type != TYPE_IGNORE)
            {
                  char *cmd = line, *is;
                  while(*cmd == ' ' || *cmd == '\t') cmd++;

                  is = strchr(cmd, '=');
                  if (is == NULL)
                  {
                        if (strchr(cmd, '}') != NULL) /* end of definition, store in array */
                        {
                              if (type == TYPE_HOST && (*pstats)[*n_stats].current_state == 1) /* HOSTS: 0=ok, 1=down, 2=unreachable */
                                    (*pstats)[*n_stats].current_state = 2;
                              (*pstats)[*n_stats].type = type;
                              (*n_stats)++;
                        }
                  }
                  else
                  {
                        int index;
                        char *record = (char *)(&(*pstats)[*n_stats]);
                        char *par = is + 1;
                        *is = 0x00;

                        if ((index = v2_0_find_entry_type(cmd)) != -1)
                        {
                              switch(v2_0_config_elements[index].type)
                              {
                                    case VARTYPE_PCHAR:
                                          *((char **)(&record[v2_0_config_elements[index].offset])) = mystrdup(par);
                                          break;
                                    case VARTYPE_INT:
                                          *((int *)(&record[v2_0_config_elements[index].offset])) = atoi(par);
                                          break;
                                    case VARTYPE_TIMET:
                                          *((time_t *)(&record[v2_0_config_elements[index].offset])) = atol(par);
                                          break;
                                    case VARTYPE_DOUBLE:
                                          *((double *)(&record[v2_0_config_elements[index].offset])) = atof(par);
                                          break;
                              }
                        }
                        else
                        {
                              printf("{%s} ???\n", cmd);
                        }
                  }
            }

            /* this one does not use myfree() as the buffered reader does not
             * use mymalloc() and friends
             */
            free(line);
      }
}

int split_1_0_line(char *line, char **out)
{
      int out_index = 0;

      memset(out, 0x00, sizeof(char *) * V1_0_MAX_ELEMENTS);

      for(;out_index < V1_0_MAX_ELEMENTS;)
      {
            out[out_index++] = line;

            line = strchr(line, ';');

            if (!line)
                  break;

            *line = 0x00; /* replace ';' with 0x00 */
            line++;
      }

      return out_index;
}

void parse_1_0_statuslog(int fd, struct stats **pstats, int *n_stats)
{
      /* start up buffered reader */
      buffered_reader bf(fd);

      *pstats = NULL;
      *n_stats = 0;

      for(;;)
      {
            int type = TYPE_IGNORE;
            char *host_name = NULL;
            int current_state = -1;
            char *service_description = NULL;
            char *plugin_output = NULL;
            time_t last_state_change = 0;
            char active_checks_enabled = 0;
            char passive_checks_enabled = 0;
            char notifications_enabled = 0;
            char problem_has_been_acknowledged = 0;
            int scheduled_downtime_depth = 0;
            char state_type = 0;
            char last_hard_state = 0;
            int modified_attributes = 0;
            int event_handler = 0;
            int has_been_checked = 0;
            int should_be_scheduled = 0;
            int current_attempt = 0;
            int max_attempts = 0;
            int last_hard_state_change = 0;
            int last_time_ok = 0;
            int last_time_warning = 0;
            int last_time_unknown = 0;
            int last_time_critical = 0;
            time_t last_check = 0;
            time_t next_check = 0;
            int check_type = 0;
            int current_notification_number = 0;
            int last_notification = 0;
            int next_notification = 0;
            int no_more_notifications = 0;
            int event_handler_enabled = 0;
            int acknowledgement_type = 0;
            int flap_detection_enabled = 0;
            int failure_prediction_enabled = 0;
            int process_performance_data = 0;
            int obsess_over_service = 0;
            time_t last_update = 0;
            int is_flapping = 0;
            double percent_state_change = 0;
            double check_execution_time = 0;
            double check_latency = 0;
            char * performance_data = NULL;
            char * check_command = NULL;
            int last_time_up = 0;
            int last_time_down = 0;
            int last_time_unreachable = 0;

            char *dummy;
            char *elements[V1_0_MAX_ELEMENTS];
            int n_elem;
            char *line = bf.read_line();
            if (!line)
                  break;

            if (line[0] == '#')
                  goto skip_line;

            n_elem = split_1_0_line(line, elements);

            *pstats = (struct stats *)myrealloc(*pstats, ((*n_stats) + 1) * sizeof(struct stats), "stats array");
            if (!*pstats)
                  error_exit("Error allocating memory");

            memset(&(*pstats)[*n_stats], 0x00, sizeof(struct stats));

            /*
               [Time of last update] HOST;
               Host Name (string);
               Status (OK/DOWN/UNREACHABLE);
               Last Check Time (long time);
               Last State Change (long time);
               Acknowledged (0/1);
               Time Up (long time);
               Time Down (long time);
               Time Unreachable (long time);
               Last Notification Time (long time);
               Current Notification Number (#);
               Notifications Enabled (0/1);
               Event Handlers Enabled (0/1);
               Checks Enabled (0/1);
               Flap Detection Enabled (0/1);
               Host is Flapping (0/1);
               Percent State Change (###.##);
               Scheduled downtime depth (#);
               Failure Prediction Enabled (0/1);
               Process Performance Data(0/1);
               Plugin Output (string)
               */

            /*
               [Time of last update] SERVICE;
               Host Name (string);
               Service Description (string);
               Status (OK/WARNING/CRITICAL/UNKNOWN);
               Retry number (#/#);
               State Type (SOFT/HARD);
               Last check time (long time);
               Next check time (long time);
               Check type (ACTIVE/PASSIVE);
               Checks enabled (0/1);
               Accept Passive Checks (0/1);
               Event Handlers Enabled (0/1);
               Last state change (long time);
               Problem acknowledged (0/1);
               Last Hard State (OK/WARNING/CRITICAL/UNKNOWN);
               Time OK (long time);
               Time Unknown (long time);
               Time Warning (long time);
               Time Critical (long time);
               Last Notification Time (long time);
               Current Notification Number (#);
               Notifications Enabled (0/1);
               Latency (#);
               Execution Time (#);
               Flap Detection Enabled (0/1);
               Service is Flapping (0/1);
               Percent State Change (###.##);
               Scheduled Downtime Depth (#);
               Failure Prediction Enabled (0/1);
               Process Performance Date (0/1);
               Obsess Over Service (0/1);
               Plugin Output (string)
               */

            dummy = strchr(elements[0], ' ');
            if (!dummy)
                  goto skip_line;
            dummy++;
            if (strcmp(dummy, "HOST") == 0)
                  type = TYPE_HOST;
            else if (strcmp(dummy, "SERVICE") == 0)
                  type = TYPE_SERVICE;
            else if (strcmp(dummy, "PROGRAM") == 0)
                  goto skip_line;
            else
                  goto skip_line;

            last_update = atol(elements[0] + 1);

            if (type == TYPE_HOST)
            {
                  if (n_elem != 21)
                        goto skip_line;

                  host_name = mystrdup(elements[1]);
                  if (strcmp(elements[2], "UP") == 0)
                        current_state = 0;
                  else
                        current_state = 2;
                  last_check = atol(elements[3]);
                  last_state_change = atol(elements[4]);
                  problem_has_been_acknowledged = atoi(elements[5]);
                  last_time_up = atol(elements[6]);
                  last_time_down = atol(elements[7]);
                  last_time_unreachable = atol(elements[8]);
                  last_notification = atol(elements[9]);
                  current_notification_number = atoi(elements[10]);
                  notifications_enabled = atoi(elements[11]);
                  event_handler_enabled = atoi(elements[12]);
                  active_checks_enabled = atoi(elements[13]); /* in 2.0 it has been split up in passive and active */
                  flap_detection_enabled = atoi(elements[14]);
                  is_flapping = atoi(elements[15]);
                  percent_state_change = atof(elements[16]);
                  scheduled_downtime_depth = atoi(elements[17]);
                  failure_prediction_enabled = atoi(elements[18]);
                  /*                process_performance_data = atoi(elements[19]); */
                  plugin_output = mystrdup(elements[20]);
            }
            else if (type == TYPE_SERVICE)
            {
                  if (n_elem != 32)
                        goto skip_line;
                  host_name = mystrdup(elements[1]);
                  service_description = mystrdup(elements[2]);
                  if (strcmp(elements[3], "OK") == 0)
                        current_state = 0;
                  else if (strcmp(elements[3], "WARNING") == 0)
                        current_state = 1;
                  else if (strcmp(elements[3], "CRITICAL") == 0)
                        current_state = 2;
                  else if (strcmp(elements[3], "UNKNOWN") == 0 || strcmp(elements[3], "PENDING") == 0)
                        current_state = 3;
                  /*                retry_number = atoi(elements[4]); */
                  if (strcmp(elements[5], "SOFT") == 0)
                        state_type = 0;
                  else
                        state_type = 1;
                  last_check = atol(elements[6]);
                  next_check = atol(elements[7]);
                  if (strcmp(elements[8], "ACTIVE") == 0)
                        check_type = 1;
                  else
                        check_type = 0;
                  active_checks_enabled = atoi(elements[9]);
                  /*                accept_passive_checks = atoi(elements[10]); */
                  event_handler_enabled = atoi(elements[11]);
                  last_state_change = atol(elements[12]);
                  problem_has_been_acknowledged = atoi(elements[13]);
                  if (strcmp(elements[14], "OK") == 0)
                        last_hard_state = 0;
                  else if (strcmp(elements[14], "WARNING") == 0)
                        last_hard_state = 1;
                  else if (strcmp(elements[14], "CRITICAL") == 0)
                        last_hard_state = 2;
                  else if (strcmp(elements[14], "UNKNOWN") == 0)
                        last_hard_state = 3;
                  last_time_ok = atol(elements[15]);
                  last_time_unknown = atol(elements[16]);
                  last_time_warning = atol(elements[17]);
                  last_time_critical = atol(elements[18]);
                  last_notification = atol(elements[19]);
                  current_notification_number = atoi(elements[20]);
                  notifications_enabled = atoi(elements[21]);
                  check_latency = atof(elements[22]);
                  check_execution_time = atof(elements[23]);
                  flap_detection_enabled = atoi(elements[24]);
                  is_flapping = atoi(elements[25]);
                  percent_state_change = atof(elements[26]);
                  scheduled_downtime_depth = atoi(elements[27]);
                  failure_prediction_enabled = atoi(elements[28]);
                  /*                process_performance_date = atoi(elements[29]); */
                  obsess_over_service = atoi(elements[30]);
                  plugin_output = mystrdup(elements[31]);
            }
            else
                  error_exit("internal error: type %d unexpected\n", type);

            (*pstats)[*n_stats].type = type;
            (*pstats)[*n_stats].host_name = host_name?host_name:mystrdup("");
            if (type == TYPE_HOST && current_state == 1) /* HOSTS: 0=ok, 1=down, 2=unreachable */
                  current_state = 2;
            (*pstats)[*n_stats].current_state = current_state;
            (*pstats)[*n_stats].service_description = service_description?service_description:mystrdup("");
            (*pstats)[*n_stats].plugin_output = plugin_output?plugin_output:mystrdup("");
            (*pstats)[*n_stats].last_state_change = last_state_change;
            (*pstats)[*n_stats].active_checks_enabled = active_checks_enabled;
            (*pstats)[*n_stats].passive_checks_enabled = passive_checks_enabled;
            (*pstats)[*n_stats].notifications_enabled = notifications_enabled;
            (*pstats)[*n_stats].problem_has_been_acknowledged = problem_has_been_acknowledged;
            (*pstats)[*n_stats].scheduled_downtime_depth = scheduled_downtime_depth;
            (*pstats)[*n_stats].state_type = state_type;
            (*pstats)[*n_stats].last_hard_state = last_hard_state;
            (*pstats)[*n_stats].modified_attributes = modified_attributes;
            (*pstats)[*n_stats].event_handler = event_handler;
            (*pstats)[*n_stats].has_been_checked = has_been_checked;
            (*pstats)[*n_stats].should_be_scheduled = should_be_scheduled;
            (*pstats)[*n_stats].current_attempt = current_attempt;
            (*pstats)[*n_stats].max_attempts = max_attempts;
            (*pstats)[*n_stats].last_hard_state_change = last_hard_state_change;
            (*pstats)[*n_stats].last_time_ok = last_time_ok;
            (*pstats)[*n_stats].last_time_warning = last_time_warning;
            (*pstats)[*n_stats].last_time_unknown = last_time_unknown;
            (*pstats)[*n_stats].last_time_critical = last_time_critical;
            (*pstats)[*n_stats].last_check = last_check;
            (*pstats)[*n_stats].next_check = next_check;
            (*pstats)[*n_stats].check_type = check_type;
            (*pstats)[*n_stats].current_notification_number = current_notification_number;
            (*pstats)[*n_stats].last_notification = last_notification;
            (*pstats)[*n_stats].next_notification = next_notification;
            (*pstats)[*n_stats].no_more_notifications = no_more_notifications;
            (*pstats)[*n_stats].event_handler_enabled = event_handler_enabled;
            (*pstats)[*n_stats].acknowledgement_type = acknowledgement_type;
            (*pstats)[*n_stats].flap_detection_enabled = flap_detection_enabled;
            (*pstats)[*n_stats].failure_prediction_enabled = failure_prediction_enabled;
            (*pstats)[*n_stats].process_performance_data = process_performance_data;
            (*pstats)[*n_stats].obsess_over_service = obsess_over_service;
            (*pstats)[*n_stats].last_update = last_update;
            (*pstats)[*n_stats].is_flapping = is_flapping;
            (*pstats)[*n_stats].percent_state_change = percent_state_change;
            (*pstats)[*n_stats].check_execution_time = check_execution_time;
            (*pstats)[*n_stats].check_latency = check_latency;
            (*pstats)[*n_stats].performance_data = performance_data;
            (*pstats)[*n_stats].check_command = check_command;
            (*pstats)[*n_stats].last_time_up = last_time_up;
            (*pstats)[*n_stats].last_time_down = last_time_down;
            (*pstats)[*n_stats].last_time_unreachable = last_time_unreachable;
            (*n_stats)++;

skip_line:
            free(line);
      }

      close(fd);
}

void free_stats_array(struct stats *pstats, int n_stats)
{
      if (pstats)
      {
            for(int loop=0; loop<n_stats; loop++)
            {
                  myfree(pstats[loop].host_name, "entry hostname");
                  myfree(pstats[loop].service_description, "entry servicedescription");
                  myfree(pstats[loop].plugin_output, "entry plugin output");
                  myfree(pstats[loop].performance_data, "entry performance data");
                  myfree(pstats[loop].check_command, "entry check command");
                  myfree(pstats[loop].author, "entry author");
                  myfree(pstats[loop].check_period, "entry check_period");
                  myfree(pstats[loop].comment_data, "entry comment data");
                  myfree(pstats[loop].host_notification_period, "entry host notification period");
                  myfree(pstats[loop].long_plugin_output, "entry long plugin output");
                  myfree(pstats[loop].notification_period, "entry notification period");
                  myfree(pstats[loop].service_notification_period, "entry service notification period");
            }

            myfree(pstats, "stats array");
      }
}

int sort_compare_func(const void *a, const void *b)
{
      struct stats *p1 = (struct stats *)a;
      struct stats *p2 = (struct stats *)b;

      if (p1 -> current_state < p2 -> current_state)
            return 1;
      else if (p1 -> current_state == p2 -> current_state)
      {
            if (p1 -> last_state_change < p2 -> last_state_change)
                  return 1;

            return p2 -> last_state_change - p1 -> last_state_change;
      }

      return -1;
}

void sort_stats_array(struct stats *pstats, int n_stats)
{
      if (n_stats > 1)
            qsort(pstats, n_stats, sizeof(struct stats), sort_compare_func);
}

int host_is_down(struct stats *pstats, int n_stats, char *host_name)
{
      for(int loop=0; loop<n_stats; loop++)
      {
            if (pstats[loop].type == TYPE_SERVICE)
                  continue;

            if (pstats[loop].current_state == 1 || // down
                        pstats[loop].current_state == 2) // unreachable
            {
                  if (pstats[loop].host_name != NULL && strcmp(pstats[loop].host_name, host_name) == 0)
                        return loop;
            }
      }

      return -1;
}

int should_i_show_entry(struct stats *pstats, int n_stats, int cur_index, char list_all_problems, char always_notify, char also_acknowledged, char hide_ok)
{
      if (pstats[cur_index].state_type != 1)
            return 0;

      if (!list_all_problems)
      {
            if (pstats[cur_index].type != TYPE_HOST && host_is_down(pstats, n_stats, pstats[cur_index].host_name) != -1)
                  return 0;

            if (pstats[cur_index].active_checks_enabled == 0 &&
                        pstats[cur_index].passive_checks_enabled == 0)
                  return 0;

            if (pstats[cur_index].scheduled_downtime_depth != 0)
                  return 0;
      }

      if (!always_notify && pstats[cur_index].notifications_enabled == 0)
            return 0;

      if (!also_acknowledged && pstats[cur_index].problem_has_been_acknowledged == 1)
            return 0;

      if (pstats[cur_index].current_state == 0 && hide_ok)
            return 0;

      if (pstats[cur_index].current_state < 0 || pstats[cur_index].current_state > 3)
            error_exit("internal error: state %d not known", pstats[cur_index].current_state);

      return 1;
}

int find_index_by_host_and_service(struct stats *pstats, int n_stats, char *host_name, char *service_description)
{
      int loop;
      static int last = 0;

      if (service_description)
      {
            for(loop=0; loop<n_stats; loop++)
            {
                  int index = (last + loop) % n_stats;
                  if (pstats[index].host_name != NULL && strcmp(pstats[index].host_name, host_name) == 0 &&
                              pstats[index].service_description != NULL && strcmp(pstats[index].service_description, service_description) == 0)
                  {
                        last = index;
                        return index;
                  }
            }
      }
      else
      {
            for(loop=0; loop<n_stats; loop++)
            {
                  int index = (last + loop) % n_stats;
                  if (pstats[index].service_description == NULL && pstats[index].host_name != NULL && strcmp(pstats[index].host_name, host_name) == 0)
                  {
                        last = index;
                        return index;
                  }
            }
      }

      return -1;
}

int check_an_age(char **message, char *descr, time_t now, time_t check_time, int max_diff, char *what)
{
      char buffer[4096] = { 0 };
      int cur_diff = (now - check_time);

      *message = 0x00;

      if (cur_diff > max_diff)
      {
            char *time_str = ctime(&check_time);
            char *dummy = strchr(time_str, '\n');
            *dummy = 0x00;

            snprintf(buffer, sizeof(buffer), "limit reached of \"%s\" for %s: %d seconds (last check: %s (%d), max diff: %d)", descr, what?what:"?", cur_diff, time_str, (int)check_time, max_diff);

            *message = strdup(buffer);

            return -1;
      }

      return 0;
}

int check_max_age_last_check(struct stats *pstats, int n_stats, int max_time_last_host_update, int max_time_oldest_host_update, int max_time_last_host_check, int max_time_oldest_host_check, int max_time_last_service_check, int max_time_oldest_service_check, int max_time_oldest_next_service_check, char **message)
{
      time_t now = time(NULL);
      int index;
      time_t most_recent_host_update = 0;
      time_t most_recent_host_check  = 0;
      time_t most_recent_last_service_check = 0;
      time_t oldest_next_service_check = now;

      for(index=0; index<n_stats; index++)
      {
            if (pstats[index].type == TYPE_HOST)
            {
                  if (pstats[index].last_update != 0)
                  {
                        most_recent_host_update = max(most_recent_host_update, pstats[index].last_update);

                        if (check_an_age(message, "oldest host update", now, pstats[index].last_update, max_time_oldest_host_update, pstats[index].host_name) == -1)
                              return -1;
                  }

                  if (pstats[index].last_check != 0)
                  {
                        most_recent_host_check = max(most_recent_host_check, pstats[index].last_check);

                        // if (check_an_age(message, "oldest host check", now, pstats[index].last_check, max_time_oldest_host_check, pstats[index].host_name) == -1)
                        //    return -1;
                  }
            }
            else if (pstats[index].type == TYPE_SERVICE)
            {
                  if (pstats[index].last_check != 0)
                  {
                        char buffer[4096];

                        snprintf(buffer, sizeof(buffer), "%s@%s", pstats[index].service_description, pstats[index].host_name);

                        most_recent_last_service_check = max(most_recent_last_service_check, pstats[index].last_check);

                        if (check_an_age(message, "oldest service check", now, pstats[index].last_check, max_time_oldest_service_check, buffer) == -1)
                              return -1;
                  }

                  if (pstats[index].next_check != 0)
                  {
                        oldest_next_service_check = min(oldest_next_service_check, pstats[index].next_check);
                  }
            }
      }

      if (check_an_age(message, "most recent host update", now, most_recent_host_update, max_time_last_host_update, NULL) == -1)
            return -1;

      // if (check_an_age(message, "most recent host check", now, most_recent_host_check, max_time_last_host_check, NULL) == -1)
      //    return -1;

      if (check_an_age(message, "most recent last service check", now, most_recent_last_service_check, max_time_last_service_check, NULL) == -1)
            return -1;

      if (check_an_age(message, "oldest next sevice check", now, oldest_next_service_check, max_time_oldest_next_service_check, NULL) == -1)
            return -1;

      return 0;
}

void calc_stats_stats(struct stats *pstats, int n_stats, char list_all_problems, char always_notify, char also_acknowledged, char hide_ok, int *n_critical, int *n_warning, int *n_ok, int *n_up, int *n_down, int *n_unreachable, int *n_pending)
{
      *n_critical = *n_warning = *n_ok = 0;
      *n_up = *n_down = *n_unreachable = *n_pending = 0;

      for(int loop=0; loop<n_stats; loop++)
      {
            if (pstats[loop].type == TYPE_HOST)
            {
                  if (pstats[loop].current_state == 0)
                        (*n_up)++;
                  else if (pstats[loop].current_state == 1)
                        (*n_down)++;
                  else if (pstats[loop].current_state == 2)
                        (*n_unreachable)++;
                  else if (pstats[loop].current_state == 3)
                        (*n_pending)++;
            }
            else if (pstats[loop].type == TYPE_SERVICE)
            {
                  if (pstats[loop].current_state == 0)
                        (*n_ok)++;
                  else if (pstats[loop].current_state == 1)
                        (*n_warning)++;
                  else if (pstats[loop].current_state == 2)
                        (*n_critical)++;
            }
            else
                  error_exit("calc_stats_stats: internal error (%d)", pstats[loop].type);
      }
}

Generated by  Doxygen 1.6.0   Back to index