static void sysconfig_notify(notification_t *notif, const char *type, const char *message) {
        memset (notif, '\0', sizeof (*notif));
        notif->severity = NOTIF_OKAY;
        notif->time = cdtime ();
        sstrncpy(notif->host, hostname_g, sizeof(notif->host));
        sstrncpy(notif->plugin, "sysconfig", sizeof(notif->plugin));
        sstrncpy(notif->type, type, sizeof(notif->type));
        sstrncpy(notif->message, message, sizeof(notif->message));
        plugin_dispatch_notification(notif);
}
Exemple #2
0
static void smart_handle_disk_attribute(SkDisk *d, const SkSmartAttributeParsedData *a,
                                        void* userdata)
{
  const char *dev = userdata;
  value_t values[4];
  value_list_t vl = VALUE_LIST_INIT;

  if (!a->current_value_valid || !a->worst_value_valid) return;
  values[0].gauge = a->current_value;
  values[1].gauge = a->worst_value;
  values[2].gauge = a->threshold_valid?a->threshold:0;
  values[3].gauge = a->pretty_value;

  vl.values = values;
  vl.values_len = 4;
  sstrncpy (vl.host, hostname_g, sizeof (vl.host));
  sstrncpy (vl.plugin, "smart", sizeof (vl.plugin));
  sstrncpy (vl.plugin_instance, dev, sizeof (vl.plugin_instance));
  sstrncpy (vl.type, "smart_attribute", sizeof (vl.type));
  sstrncpy (vl.type_instance, a->name, sizeof (vl.type_instance));

  plugin_dispatch_values (&vl);

  if (a->threshold_valid && a->current_value <= a->threshold)
  {
    notification_t notif = { NOTIF_WARNING,
                             cdtime (),
                             "",
                             "",
                             "smart", "",
                             "smart_attribute",
                             "",
                             NULL };
    sstrncpy (notif.host, hostname_g, sizeof (notif.host));
    sstrncpy (notif.plugin_instance, dev, sizeof (notif.plugin_instance));
    sstrncpy (notif.type_instance, a->name, sizeof (notif.type_instance));
    ssnprintf (notif.message, sizeof (notif.message),
               "attribute %s is below allowed threshold (%d < %d)",
               a->name, a->current_value, a->threshold);
    plugin_dispatch_notification (&notif);
  }
}
Exemple #3
0
/*
 * int ut_report_state
 *
 * Checks if the `state' differs from the old state and creates a notification
 * if appropriate.
 * Does not fail.
 */
static int ut_report_state(const data_set_t *ds, const value_list_t *vl,
                           const threshold_t *th, const gauge_t *values,
                           int ds_index, int state) { /* {{{ */
  int state_old;
  notification_t n;

  char *buf;
  size_t bufsize;

  int status;

  /* Check if hits matched */
  if ((th->hits != 0)) {
    int hits = uc_get_hits(ds, vl);
    /* STATE_OKAY resets hits unless PERSIST_OK flag is set. Hits resets if
     * threshold is hit. */
    if (((state == STATE_OKAY) && ((th->flags & UT_FLAG_PERSIST_OK) == 0)) ||
        (hits > th->hits)) {
      DEBUG("ut_report_state: reset uc_get_hits = 0");
      uc_set_hits(ds, vl, 0); /* reset hit counter and notify */
    } else {
      DEBUG("ut_report_state: th->hits = %d, uc_get_hits = %d", th->hits,
            uc_get_hits(ds, vl));
      (void)uc_inc_hits(ds, vl, 1); /* increase hit counter */
      return 0;
    }
  } /* end check hits */

  state_old = uc_get_state(ds, vl);

  /* If the state didn't change, report if `persistent' is specified. If the
   * state is `okay', then only report if `persist_ok` flag is set. */
  if (state == state_old) {
    if ((th->flags & UT_FLAG_PERSIST) == 0)
      return 0;
    else if ((state == STATE_OKAY) && ((th->flags & UT_FLAG_PERSIST_OK) == 0))
      return 0;
  }

  if (state != state_old)
    uc_set_state(ds, vl, state);

  NOTIFICATION_INIT_VL(&n, vl);

  buf = n.message;
  bufsize = sizeof(n.message);

  if (state == STATE_OKAY)
    n.severity = NOTIF_OKAY;
  else if (state == STATE_WARNING)
    n.severity = NOTIF_WARNING;
  else
    n.severity = NOTIF_FAILURE;

  n.time = vl->time;

  status = snprintf(buf, bufsize, "Host %s, plugin %s", vl->host, vl->plugin);
  buf += status;
  bufsize -= status;

  if (vl->plugin_instance[0] != '\0') {
    status = snprintf(buf, bufsize, " (instance %s)", vl->plugin_instance);
    buf += status;
    bufsize -= status;
  }

  status = snprintf(buf, bufsize, " type %s", vl->type);
  buf += status;
  bufsize -= status;

  if (vl->type_instance[0] != '\0') {
    status = snprintf(buf, bufsize, " (instance %s)", vl->type_instance);
    buf += status;
    bufsize -= status;
  }

  plugin_notification_meta_add_string(&n, "DataSource", ds->ds[ds_index].name);
  plugin_notification_meta_add_double(&n, "CurrentValue", values[ds_index]);
  plugin_notification_meta_add_double(&n, "WarningMin", th->warning_min);
  plugin_notification_meta_add_double(&n, "WarningMax", th->warning_max);
  plugin_notification_meta_add_double(&n, "FailureMin", th->failure_min);
  plugin_notification_meta_add_double(&n, "FailureMax", th->failure_max);

  /* Send an okay notification */
  if (state == STATE_OKAY) {
    if (state_old == STATE_MISSING)
      snprintf(buf, bufsize, ": Value is no longer missing.");
    else
      snprintf(buf, bufsize, ": All data sources are within range again. "
                             "Current value of \"%s\" is %f.",
               ds->ds[ds_index].name, values[ds_index]);
  } else {
    double min;
    double max;

    min = (state == STATE_ERROR) ? th->failure_min : th->warning_min;
    max = (state == STATE_ERROR) ? th->failure_max : th->warning_max;

    if (th->flags & UT_FLAG_INVERT) {
      if (!isnan(min) && !isnan(max)) {
        snprintf(buf, bufsize,
                 ": Data source \"%s\" is currently "
                 "%f. That is within the %s region of %f%s and %f%s.",
                 ds->ds[ds_index].name, values[ds_index],
                 (state == STATE_ERROR) ? "failure" : "warning", min,
                 ((th->flags & UT_FLAG_PERCENTAGE) != 0) ? "%" : "", max,
                 ((th->flags & UT_FLAG_PERCENTAGE) != 0) ? "%" : "");
      } else {
        snprintf(buf, bufsize, ": Data source \"%s\" is currently "
                               "%f. That is %s the %s threshold of %f%s.",
                 ds->ds[ds_index].name, values[ds_index],
                 isnan(min) ? "below" : "above",
                 (state == STATE_ERROR) ? "failure" : "warning",
                 isnan(min) ? max : min,
                 ((th->flags & UT_FLAG_PERCENTAGE) != 0) ? "%" : "");
      }
    } else if (th->flags & UT_FLAG_PERCENTAGE) {
      gauge_t value;
      gauge_t sum;

      sum = 0.0;
      for (size_t i = 0; i < vl->values_len; i++) {
        if (isnan(values[i]))
          continue;

        sum += values[i];
      }

      if (sum == 0.0)
        value = NAN;
      else
        value = 100.0 * values[ds_index] / sum;

      snprintf(buf, bufsize,
               ": Data source \"%s\" is currently "
               "%g (%.2f%%). That is %s the %s threshold of %.2f%%.",
               ds->ds[ds_index].name, values[ds_index], value,
               (value < min) ? "below" : "above",
               (state == STATE_ERROR) ? "failure" : "warning",
               (value < min) ? min : max);
    } else /* is not inverted */
    {
      snprintf(buf, bufsize, ": Data source \"%s\" is currently "
                             "%f. That is %s the %s threshold of %f.",
               ds->ds[ds_index].name, values[ds_index],
               (values[ds_index] < min) ? "below" : "above",
               (state == STATE_ERROR) ? "failure" : "warning",
               (values[ds_index] < min) ? min : max);
    }
  }

  plugin_dispatch_notification(&n);

  plugin_notification_meta_free(n.meta);
  return 0;
} /* }}} int ut_report_state */
Exemple #4
0
/*
 * int ut_report_state
 *
 * Checks if the `state' differs from the old state and creates a notification
 * if appropriate.
 * Does not fail.
 */
static int ut_report_state (const data_set_t *ds,
    const value_list_t *vl,
    const threshold_t *th,
    const gauge_t *values,
    int ds_index,
    int state)
{ /* {{{ */
  int state_old;
  notification_t n;

  char *buf;
  size_t bufsize;

  int status;

  state_old = uc_get_state (ds, vl);

  /* If the state didn't change, only report if `persistent' is specified and
   * the state is not `okay'. */
  if (state == state_old)
  {
    if ((th->flags & UT_FLAG_PERSIST) == 0)
      return (0);
    else if (state == STATE_OKAY)
      return (0);
  }

  if (state != state_old)
    uc_set_state (ds, vl, state);

  NOTIFICATION_INIT_VL (&n, vl, ds);

  buf = n.message;
  bufsize = sizeof (n.message);

  if (state == STATE_OKAY)
    n.severity = NOTIF_OKAY;
  else if (state == STATE_WARNING)
    n.severity = NOTIF_WARNING;
  else
    n.severity = NOTIF_FAILURE;

  n.time = vl->time;

  status = ssnprintf (buf, bufsize, "Host %s, plugin %s",
      vl->host, vl->plugin);
  buf += status;
  bufsize -= status;

  if (vl->plugin_instance[0] != '\0')
  {
    status = ssnprintf (buf, bufsize, " (instance %s)",
	vl->plugin_instance);
    buf += status;
    bufsize -= status;
  }

  status = ssnprintf (buf, bufsize, " type %s", vl->type);
  buf += status;
  bufsize -= status;

  if (vl->type_instance[0] != '\0')
  {
    status = ssnprintf (buf, bufsize, " (instance %s)",
	vl->type_instance);
    buf += status;
    bufsize -= status;
  }

  plugin_notification_meta_add_string (&n, "DataSource",
      ds->ds[ds_index].name);
  plugin_notification_meta_add_double (&n, "CurrentValue", values[ds_index]);
  plugin_notification_meta_add_double (&n, "WarningMin", th->warning_min);
  plugin_notification_meta_add_double (&n, "WarningMax", th->warning_max);
  plugin_notification_meta_add_double (&n, "FailureMin", th->failure_min);
  plugin_notification_meta_add_double (&n, "FailureMax", th->failure_max);

  /* Send an okay notification */
  if (state == STATE_OKAY)
  {
    status = ssnprintf (buf, bufsize, ": All data sources are within range again.");
    buf += status;
    bufsize -= status;
  }
  else
  {
    double min;
    double max;

    min = (state == STATE_ERROR) ? th->failure_min : th->warning_min;
    max = (state == STATE_ERROR) ? th->failure_max : th->warning_max;

    if (th->flags & UT_FLAG_INVERT)
    {
      if (!isnan (min) && !isnan (max))
      {
	status = ssnprintf (buf, bufsize, ": Data source \"%s\" is currently "
	    "%f. That is within the %s region of %f and %f.",
	    ds->ds[ds_index].name, values[ds_index],
	    (state == STATE_ERROR) ? "failure" : "warning",
	    min, max);
      }
      else
      {
	status = ssnprintf (buf, bufsize, ": Data source \"%s\" is currently "
	    "%f. That is %s the %s threshold of %f.",
	    ds->ds[ds_index].name, values[ds_index],
	    isnan (min) ? "below" : "above",
	    (state == STATE_ERROR) ? "failure" : "warning",
	    isnan (min) ? max : min);
      }
    }
    else /* is not inverted */
    {
      status = ssnprintf (buf, bufsize, ": Data source \"%s\" is currently "
	  "%f. That is %s the %s threshold of %f.",
	  ds->ds[ds_index].name, values[ds_index],
	  (values[ds_index] < min) ? "below" : "above",
	  (state == STATE_ERROR) ? "failure" : "warning",
	  (values[ds_index] < min) ? min : max);
    }
    buf += status;
    bufsize -= status;
  }

  plugin_dispatch_notification (&n);

  plugin_notification_meta_free (n.meta);
  return (0);
} /* }}} int ut_report_state */
Exemple #5
0
static int mysql_read_slave_stats (mysql_database_t *db, MYSQL *con)
{
	MYSQL_RES *res;
	MYSQL_ROW  row;

	char *query;
	int   field_num;

	/* WTF? libmysqlclient does not seem to provide any means to
	 * translate a column name to a column index ... :-/ */
	const int READ_MASTER_LOG_POS_IDX   = 6;
	const int SLAVE_IO_RUNNING_IDX      = 10;
	const int SLAVE_SQL_RUNNING_IDX     = 11;
	const int EXEC_MASTER_LOG_POS_IDX   = 21;
	const int SECONDS_BEHIND_MASTER_IDX = 32;

	query = "SHOW SLAVE STATUS";

	res = exec_query (con, query);
	if (res == NULL)
		return (-1);

	row = mysql_fetch_row (res);
	if (row == NULL)
	{
		ERROR ("mysql plugin: Failed to get slave statistics: "
				"`%s' did not return any rows.", query);
		mysql_free_result (res);
		return (-1);
	}

	field_num = mysql_num_fields (res);
	if (field_num < 33)
	{
		ERROR ("mysql plugin: Failed to get slave statistics: "
				"`%s' returned less than 33 columns.", query);
		mysql_free_result (res);
		return (-1);
	}

	if (db->slave_stats)
	{
		unsigned long long counter;
		double gauge;

		counter = atoll (row[READ_MASTER_LOG_POS_IDX]);
		counter_submit ("mysql_log_position", "slave-read", counter, db);

		counter = atoll (row[EXEC_MASTER_LOG_POS_IDX]);
		counter_submit ("mysql_log_position", "slave-exec", counter, db);

		if (row[SECONDS_BEHIND_MASTER_IDX] != NULL)
		{
			gauge = atof (row[SECONDS_BEHIND_MASTER_IDX]);
			gauge_submit ("time_offset", NULL, gauge, db);
		}
	}

	if (db->slave_notif)
	{
		notification_t n = { 0, cdtime (), "", "",
			"mysql", "", "time_offset", "", NULL };

		char *io, *sql;

		io  = row[SLAVE_IO_RUNNING_IDX];
		sql = row[SLAVE_SQL_RUNNING_IDX];

		set_host (db, n.host, sizeof (n.host));

		/* Assured by "mysql_config_database" */
		assert (db->instance != NULL);
		sstrncpy (n.plugin_instance, db->instance, sizeof (n.plugin_instance));

		if (((io == NULL) || (strcasecmp (io, "yes") != 0))
				&& (db->slave_io_running))
		{
			n.severity = NOTIF_WARNING;
			ssnprintf (n.message, sizeof (n.message),
					"slave I/O thread not started or not connected to master");
			plugin_dispatch_notification (&n);
			db->slave_io_running = 0;
		}
		else if (((io != NULL) && (strcasecmp (io, "yes") == 0))
				&& (! db->slave_io_running))
		{
			n.severity = NOTIF_OKAY;
			ssnprintf (n.message, sizeof (n.message),
					"slave I/O thread started and connected to master");
			plugin_dispatch_notification (&n);
			db->slave_io_running = 1;
		}

		if (((sql == NULL) || (strcasecmp (sql, "yes") != 0))
				&& (db->slave_sql_running))
		{
			n.severity = NOTIF_WARNING;
			ssnprintf (n.message, sizeof (n.message),
					"slave SQL thread not started");
			plugin_dispatch_notification (&n);
			db->slave_sql_running = 0;
		}
		else if (((sql != NULL) && (strcasecmp (sql, "yes") == 0))
				&& (! db->slave_sql_running))
		{
			n.severity = NOTIF_OKAY;
			ssnprintf (n.message, sizeof (n.message),
					"slave SQL thread started");
			plugin_dispatch_notification (&n);
			db->slave_sql_running = 0;
		}
	}

	row = mysql_fetch_row (res);
	if (row != NULL)
		WARNING ("mysql plugin: `%s' returned more than one row - "
				"ignoring further results.", query);

	mysql_free_result (res);

	return (0);
} /* mysql_read_slave_stats */
Exemple #6
0
int uc_update (const data_set_t *ds, const value_list_t *vl)
{
  char name[6 * DATA_MAX_NAME_LEN];
  cache_entry_t *ce = NULL;
  int send_okay_notification = 0;
  time_t update_delay = 0;
  notification_t n;
  int status;
  int i;

  if (FORMAT_VL (name, sizeof (name), vl) != 0)
  {
    ERROR ("uc_update: FORMAT_VL failed.");
    return (-1);
  }

  pthread_mutex_lock (&cache_lock);

  status = c_avl_get (cache_tree, name, (void *) &ce);
  if (status != 0) /* entry does not yet exist */
  {
    status = uc_insert (ds, vl, name);
    pthread_mutex_unlock (&cache_lock);
    return (status);
  }

  assert (ce != NULL);
  assert (ce->values_num == ds->ds_num);

  if (ce->last_time >= vl->time)
  {
    pthread_mutex_unlock (&cache_lock);
    NOTICE ("uc_update: Value too old: name = %s; value time = %u; "
	"last cache update = %u;",
	name, (unsigned int) vl->time, (unsigned int) ce->last_time);
    return (-1);
  }

  /* Send a notification (after the lock has been released) if we switch the
   * state from something else to `okay'. */
  if (ce->state == STATE_MISSING)
  {
    send_okay_notification = 1;
    ce->state = STATE_OKAY;
    update_delay = time (NULL) - ce->last_update;
  }

  for (i = 0; i < ds->ds_num; i++)
  {
    switch (ds->ds[i].type)
    {
      case DS_TYPE_COUNTER:
	{
	  counter_t diff;

	  /* check if the counter has wrapped around */
	  if (vl->values[i].counter < ce->values_raw[i].counter)
	  {
	    if (ce->values_raw[i].counter <= 4294967295U)
	      diff = (4294967295U - ce->values_raw[i].counter)
		+ vl->values[i].counter;
	    else
	      diff = (18446744073709551615ULL - ce->values_raw[i].counter)
		+ vl->values[i].counter;
	  }
	  else /* counter has NOT wrapped around */
	  {
	    diff = vl->values[i].counter - ce->values_raw[i].counter;
	  }

	  ce->values_gauge[i] = ((double) diff)
	    / ((double) (vl->time - ce->last_time));
	  ce->values_raw[i].counter = vl->values[i].counter;
	}
	break;

      case DS_TYPE_GAUGE:
	ce->values_raw[i].gauge = vl->values[i].gauge;
	ce->values_gauge[i] = vl->values[i].gauge;
	break;

      case DS_TYPE_DERIVE:
	{
	  derive_t diff;

	  diff = vl->values[i].derive - ce->values_raw[i].derive;

	  ce->values_gauge[i] = ((double) diff)
	    / ((double) (vl->time - ce->last_time));
	  ce->values_raw[i].derive = vl->values[i].derive;
	}
	break;

      case DS_TYPE_ABSOLUTE:
	ce->values_gauge[i] = ((double) vl->values[i].absolute)
	  / ((double) (vl->time - ce->last_time));
	ce->values_raw[i].absolute = vl->values[i].absolute;
	break;

      default:
	/* This shouldn't happen. */
	pthread_mutex_unlock (&cache_lock);
	ERROR ("uc_update: Don't know how to handle data source type %i.",
	    ds->ds[i].type);
	return (-1);
    } /* switch (ds->ds[i].type) */

    DEBUG ("uc_update: %s: ds[%i] = %lf", name, i, ce->values_gauge[i]);
  } /* for (i) */

  /* Update the history if it exists. */
  if (ce->history != NULL)
  {
    assert (ce->history_index < ce->history_length);
    for (i = 0; i < ce->values_num; i++)
    {
      size_t hist_idx = (ce->values_num * ce->history_index) + i;
      ce->history[hist_idx] = ce->values_gauge[i];
    }

    assert (ce->history_length > 0);
    ce->history_index = (ce->history_index + 1) % ce->history_length;
  }

  /* Prune invalid gauge data */
  uc_check_range (ds, ce);

  ce->last_time = vl->time;
  ce->last_update = time (NULL);
  ce->interval = vl->interval;

  pthread_mutex_unlock (&cache_lock);

  if (send_okay_notification == 0)
    return (0);

  /* Do not send okay notifications for uninteresting values, i. e. values for
   * which no threshold is configured. */
  status = ut_check_interesting (name);
  if (status <= 0)
    return (0);

  /* Initialize the notification */
  memset (&n, '\0', sizeof (n));
  NOTIFICATION_INIT_VL (&n, vl, ds);

  n.severity = NOTIF_OKAY;
  n.time = vl->time;

  ssnprintf (n.message, sizeof (n.message),
      "Received a value for %s. It was missing for %u seconds.",
      name, (unsigned int) update_delay);

  plugin_dispatch_notification (&n);

  return (0);
} /* int uc_update */
Exemple #7
0
static int uc_send_notification (const char *name)
{
  cache_entry_t *ce = NULL;
  int status;

  char *name_copy;
  char *host;
  char *plugin;
  char *plugin_instance;
  char *type;
  char *type_instance;

  notification_t n;

  name_copy = strdup (name);
  if (name_copy == NULL)
  {
    ERROR ("uc_send_notification: strdup failed.");
    return (-1);
  }

  status = parse_identifier (name_copy, &host,
      &plugin, &plugin_instance,
      &type, &type_instance);
  if (status != 0)
  {
    ERROR ("uc_send_notification: Cannot parse name `%s'", name);
    return (-1);
  }

  /* Copy the associative members */
  notification_init (&n, NOTIF_FAILURE, /* host = */ NULL,
      host, plugin, plugin_instance, type, type_instance);

  sfree (name_copy);
  name_copy = host = plugin = plugin_instance = type = type_instance = NULL;

  pthread_mutex_lock (&cache_lock);

  /*
   * Set the time _after_ getting the lock because we don't know how long
   * acquiring the lock takes and we will use this time later to decide
   * whether or not the state is OKAY.
   */
  n.time = time (NULL);

  status = c_avl_get (cache_tree, name, (void *) &ce);
  if (status != 0)
  {
    pthread_mutex_unlock (&cache_lock);
    sfree (name_copy);
    return (-1);
  }
    
  /* Check if the entry has been updated in the meantime */
  if ((n.time - ce->last_update) < (2 * ce->interval))
  {
    ce->state = STATE_OKAY;
    pthread_mutex_unlock (&cache_lock);
    sfree (name_copy);
    return (-1);
  }

  ssnprintf (n.message, sizeof (n.message),
      "%s has not been updated for %i seconds.", name,
      (int) (n.time - ce->last_update));

  pthread_mutex_unlock (&cache_lock);

  plugin_dispatch_notification (&n);

  return (0);
} /* int uc_send_notification */
int handle_putnotif(FILE *fh, char *buffer) {
  char *command;
  notification_t n = {0};
  int status;

  if ((fh == NULL) || (buffer == NULL))
    return -1;

  DEBUG("utils_cmd_putnotif: handle_putnotif (fh = %p, buffer = %s);",
        (void *)fh, buffer);

  command = NULL;
  status = parse_string(&buffer, &command);
  if (status != 0) {
    print_to_socket(fh, "-1 Cannot parse command.\n");
    return -1;
  }
  assert(command != NULL);

  if (strcasecmp("PUTNOTIF", command) != 0) {
    print_to_socket(fh, "-1 Unexpected command: `%s'.\n", command);
    return -1;
  }

  status = 0;
  while (*buffer != 0) {
    char *key;
    char *value;

    status = parse_option(&buffer, &key, &value);
    if (status != 0) {
      print_to_socket(fh, "-1 Malformed option.\n");
      break;
    }

    status = set_option(&n, key, value);
    if (status != 0) {
      print_to_socket(fh, "-1 Error parsing option `%s'\n", key);
      break;
    }
  } /* for (i) */

  /* Check for required fields and complain if anything is missing. */
  if ((status == 0) && (n.severity == 0)) {
    print_to_socket(fh, "-1 Option `severity' missing.\n");
    status = -1;
  }
  if ((status == 0) && (n.time == 0)) {
    print_to_socket(fh, "-1 Option `time' missing.\n");
    status = -1;
  }
  if ((status == 0) && (strlen(n.message) == 0)) {
    print_to_socket(fh, "-1 No message or message of length 0 given.\n");
    status = -1;
  }

  /* If status is still zero the notification is fine and we can finally
   * dispatch it. */
  if (status == 0) {
    plugin_dispatch_notification(&n);
    print_to_socket(fh, "0 Success\n");
  }

  return 0;
} /* int handle_putnotif */
static int parse_packet (void *se, /* {{{ */
    void *buffer, size_t buffer_size, int flags,
    const char *username)
{
  int status;

  value_list_t vl = VALUE_LIST_INIT;
  notification_t n;

#if HAVE_LIBGCRYPT
  int packet_was_signed = (flags & PP_SIGNED);
        int packet_was_encrypted = (flags & PP_ENCRYPTED);
  int printed_ignore_warning = 0;
#endif /* HAVE_LIBGCRYPT */


  memset (&vl, '\0', sizeof (vl));
  memset (&n, '\0', sizeof (n));
  status = 0;

  while ((status == 0) && (0 < buffer_size)
      && ((unsigned int) buffer_size > sizeof (part_header_t)))
  {
    uint16_t pkg_length;
    uint16_t pkg_type;

    memcpy ((void *) &pkg_type,
        (void *) buffer,
        sizeof (pkg_type));
    memcpy ((void *) &pkg_length,
        (void *) (buffer + sizeof (pkg_type)),
        sizeof (pkg_length));

    pkg_length = ntohs (pkg_length);
    pkg_type = ntohs (pkg_type);

    if (pkg_length > buffer_size)
      break;
    /* Ensure that this loop terminates eventually */
    if (pkg_length < (2 * sizeof (uint16_t)))
      break;

    if (pkg_type == TYPE_ENCR_AES256)
    {
      // status = parse_part_encr_aes256 (se,
      //     &buffer, &buffer_size, flags);
      // if (status != 0)
      // {
        ERROR ("network plugin: Decrypting AES256 "
            "part failed "
            "with status %i.", status);
        break;
      // }
    }
#if HAVE_LIBGCRYPT
    else if ((se->data.server.security_level == SECURITY_LEVEL_ENCRYPT)
        && (packet_was_encrypted == 0))
    {
      if (printed_ignore_warning == 0)
      {
        INFO ("network plugin: Unencrypted packet or "
            "part has been ignored.");
        printed_ignore_warning = 1;
      }
      buffer = ((char *) buffer) + pkg_length;
      continue;
    }
#endif /* HAVE_LIBGCRYPT */
    else if (pkg_type == TYPE_SIGN_SHA256)
    {
      // status = parse_part_sign_sha256 (se,
      //                                   &buffer, &buffer_size, flags);
      // if (status != 0)
      // {
        ERROR ("network plugin: Verifying HMAC-SHA-256 "
            "signature failed "
            "with status %i.", status);
        break;
      // }
    }
#if HAVE_LIBGCRYPT
    else if ((se->data.server.security_level == SECURITY_LEVEL_SIGN)
        && (packet_was_encrypted == 0)
        && (packet_was_signed == 0))
    {
      if (printed_ignore_warning == 0)
      {
        INFO ("network plugin: Unsigned packet or "
            "part has been ignored.");
        printed_ignore_warning = 1;
      }
      buffer = ((char *) buffer) + pkg_length;
      continue;
    }
#endif /* HAVE_LIBGCRYPT */
    else if (pkg_type == TYPE_VALUES)
    {
      status = parse_part_values (&buffer, &buffer_size,
          &vl.values, &vl.values_len);
      if (status != 0)
        break;

      network_dispatch_values (&vl, username);

      sfree (vl.values);
    }
    else if (pkg_type == TYPE_TIME)
    {
      uint64_t tmp = 0;
      status = parse_part_number (&buffer, &buffer_size,
          &tmp);
      if (status == 0)
      {
        vl.time = (time_t) tmp;
        n.time = (time_t) tmp;
      }
    }
    else if (pkg_type == TYPE_INTERVAL)
    {
      uint64_t tmp = 0;
      status = parse_part_number (&buffer, &buffer_size,
          &tmp);
      if (status == 0)
        vl.interval = (int) tmp;
    }
    else if (pkg_type == TYPE_HOST)
    {
      status = parse_part_string (&buffer, &buffer_size,
          vl.host, sizeof (vl.host));
      if (status == 0)
        sstrncpy (n.host, vl.host, sizeof (n.host));
    }
    else if (pkg_type == TYPE_PLUGIN)
    {
      status = parse_part_string (&buffer, &buffer_size,
          vl.plugin, sizeof (vl.plugin));
      if (status == 0)
        sstrncpy (n.plugin, vl.plugin,
            sizeof (n.plugin));
    }
    else if (pkg_type == TYPE_PLUGIN_INSTANCE)
    {
      status = parse_part_string (&buffer, &buffer_size,
          vl.plugin_instance,
          sizeof (vl.plugin_instance));
      if (status == 0)
        sstrncpy (n.plugin_instance,
            vl.plugin_instance,
            sizeof (n.plugin_instance));
    }
    else if (pkg_type == TYPE_TYPE)
    {
      status = parse_part_string (&buffer, &buffer_size,
          vl.type, sizeof (vl.type));
      if (status == 0)
        sstrncpy (n.type, vl.type, sizeof (n.type));
    }
    else if (pkg_type == TYPE_TYPE_INSTANCE)
    {
      status = parse_part_string (&buffer, &buffer_size,
          vl.type_instance,
          sizeof (vl.type_instance));
      if (status == 0)
        sstrncpy (n.type_instance, vl.type_instance,
            sizeof (n.type_instance));
    }
    else if (pkg_type == TYPE_MESSAGE)
    {
      status = parse_part_string (&buffer, &buffer_size,
          n.message, sizeof (n.message));

      if (status != 0)
      {
        /* do nothing */
      }
      else if ((n.severity != NOTIF_FAILURE)
          && (n.severity != NOTIF_WARNING)
          && (n.severity != NOTIF_OKAY))
      {
        INFO ("network plugin: "
            "Ignoring notification with "
            "unknown severity %i.",
            n.severity);
      }
      else if (n.time <= 0)
      {
        INFO ("network plugin: "
            "Ignoring notification with "
            "time == 0.");
      }
      else if (strlen (n.message) <= 0)
      {
        INFO ("network plugin: "
            "Ignoring notification with "
            "an empty message.");
      }
      else
      {
        plugin_dispatch_notification (&n);
      }
    }
    else if (pkg_type == TYPE_SEVERITY)
    {
      uint64_t tmp = 0;
      status = parse_part_number (&buffer, &buffer_size,
          &tmp);
      if (status == 0)
        n.severity = (int) tmp;
    }
    else
    {
      DEBUG ("network plugin: parse_packet: Unknown part"
          " type: 0x%04hx", pkg_type);
      buffer = ((char *) buffer) + pkg_length;
    }
  } /* while (buffer_size > sizeof (part_header_t)) */

  if (status == 0 && buffer_size > 0)
    WARNING ("network plugin: parse_packet: Received truncated "
        "packet, try increasing `MaxPacketSize'");

  return (status);
} /* }}} int parse_packet */
Exemple #10
0
static int top_read(void)
{
    struct dirent **namelist;
    int n;
    n = scandir ("/proc", &namelist, 0, alphasort);
    if (n < 0)
        perror ("scandir");
    else {
        int hz;
        hz = sysconf(_SC_CLK_TCK);
        char *bufferout;
        notification_t notif;
        memset (&notif, '\0', sizeof (n));
        bufferout = malloc(n * sizeof(char) * 256);
        *bufferout = '\0';
        //printf("pid ppid    uid user gid group rss stime    utime  name\n");
        while (n--) {
            if (atoi (namelist[n]->d_name)) {
                stat_t *stat;
                stat = malloc(sizeof(stat_t));
                //if (getStat (atoi (namelist[n]->d_name), stat) == 0 || stat->ppid == 2 || stat->ppid == 0) {
                if (getStat (atoi (namelist[n]->d_name), stat) == 0) {
                    free(namelist[n]);
                    free(stat);
                    continue;
                }
                status_t *status;
                status = malloc(sizeof(status_t));
                if (getStatus (atoi (namelist[n]->d_name), status) == 0) {
                    free(namelist[n]);
                    free(stat);
                    free(status);
                }
                char buf[256];
                struct passwd *pwd;
                pwd = getpwuid(status->Uid[1]);
                struct group *grp;
                grp = getgrgid(status->Gid[1]);
#if KERNEL_LINUX              
                snprintf(buf, sizeof(buf), "%d %d %lu %s %lu %s %ld %ld %ld %s\n", 
                    stat->pid, stat->ppid, status->Uid[1], pwd->pw_name, status->Gid[1], 
                    grp->gr_name, stat->rss, stat->stime * 100 / hz,
                    stat->utime * 100 / hz, status->Name);
#elif KERNEL_SOLARIS
               snprintf (buf, sizeof (buf), "%d %d %lu %s %lu %s %ld %ld %ld %s\n",
                        stat->pid, stat->ppid, status->Uid[1], pwd->pw_name, status->Gid[1],
                        grp->gr_name, stat->rss, stat->stime,
                        stat->utime, status->Name);   
#endif 
                free(namelist[n]);
                free(stat);
                free(status);
                strncat(bufferout, buf, sizeof(buf));
            }
        }
        //ERROR("%s", bufferout);
        notif.severity = NOTIF_OKAY;
        notif.time = cdtime ();
        sstrncpy(notif.host, hostname_g, sizeof(notif.host));
        sstrncpy(notif.plugin, "top", sizeof(notif.plugin));
        sstrncpy(notif.type, "ps", sizeof(notif.type));
        sstrncpy(notif.message, bufferout, sizeof(notif.message));
        plugin_dispatch_notification(&notif);
        free(bufferout);
    }
    free(namelist);
    return 0;
}