示例#1
0
文件: amqp.c 项目: EMSL-MSC/collectd
/* XXX: You must hold "conf->lock" when calling this function! */
static int camqp_write_locked(camqp_config_t *conf, /* {{{ */
                              const char *buffer, const char *routing_key) {
  int status;

  status = camqp_connect(conf);
  if (status != 0)
    return status;

  amqp_basic_properties_t props = {._flags = AMQP_BASIC_CONTENT_TYPE_FLAG |
                                             AMQP_BASIC_DELIVERY_MODE_FLAG |
                                             AMQP_BASIC_APP_ID_FLAG,
                                   .delivery_mode = conf->delivery_mode,
                                   .app_id = amqp_cstring_bytes("collectd")};

  if (conf->format == CAMQP_FORMAT_COMMAND)
    props.content_type = amqp_cstring_bytes("text/collectd");
  else if (conf->format == CAMQP_FORMAT_JSON)
    props.content_type = amqp_cstring_bytes("application/json");
  else if (conf->format == CAMQP_FORMAT_GRAPHITE)
    props.content_type = amqp_cstring_bytes("text/graphite");
  else
    assert(23 == 42);

  status = amqp_basic_publish(
      conf->connection,
      /* channel = */ 1, amqp_cstring_bytes(CONF(conf, exchange)),
      amqp_cstring_bytes(routing_key),
      /* mandatory = */ 0,
      /* immediate = */ 0, &props, amqp_cstring_bytes(buffer));
  if (status != 0) {
    ERROR("amqp plugin: amqp_basic_publish failed with status %i.", status);
    camqp_close_connection(conf);
  }

  return status;
} /* }}} int camqp_write_locked */

static int camqp_write(const data_set_t *ds, const value_list_t *vl, /* {{{ */
                       user_data_t *user_data) {
  camqp_config_t *conf = user_data->data;
  char routing_key[6 * DATA_MAX_NAME_LEN];
  char buffer[8192];
  int status;

  if ((ds == NULL) || (vl == NULL) || (conf == NULL))
    return EINVAL;

  if (conf->routing_key != NULL) {
    sstrncpy(routing_key, conf->routing_key, sizeof(routing_key));
  } else {
    snprintf(routing_key, sizeof(routing_key), "collectd/%s/%s/%s/%s/%s",
             vl->host, vl->plugin, vl->plugin_instance, vl->type,
             vl->type_instance);

    /* Switch slashes (the only character forbidden by collectd) and dots
     * (the separation character used by AMQP). */
    for (size_t i = 0; routing_key[i] != 0; i++) {
      if (routing_key[i] == '.')
        routing_key[i] = '/';
      else if (routing_key[i] == '/')
        routing_key[i] = '.';
    }
  }

  if (conf->format == CAMQP_FORMAT_COMMAND) {
    status = cmd_create_putval(buffer, sizeof(buffer), ds, vl);
    if (status != 0) {
      ERROR("amqp plugin: cmd_create_putval failed with status %i.", status);
      return status;
    }
  } else if (conf->format == CAMQP_FORMAT_JSON) {
    size_t bfree = sizeof(buffer);
    size_t bfill = 0;

    format_json_initialize(buffer, &bfill, &bfree);
    format_json_value_list(buffer, &bfill, &bfree, ds, vl, conf->store_rates);
    format_json_finalize(buffer, &bfill, &bfree);
  } else if (conf->format == CAMQP_FORMAT_GRAPHITE) {
    status =
        format_graphite(buffer, sizeof(buffer), ds, vl, conf->prefix,
                        conf->postfix, conf->escape_char, conf->graphite_flags);
    if (status != 0) {
      ERROR("amqp plugin: format_graphite failed with status %i.", status);
      return status;
    }
  } else {
    ERROR("amqp plugin: Invalid format (%i).", conf->format);
    return -1;
  }

  pthread_mutex_lock(&conf->lock);
  status = camqp_write_locked(conf, buffer, routing_key);
  pthread_mutex_unlock(&conf->lock);

  return status;
} /* }}} int camqp_write */
示例#2
0
static int ut_config_type(const threshold_t *th_orig, oconfig_item_t *ci) {
  threshold_t th;
  int status = 0;

  if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
    WARNING("threshold values: The `Type' block needs exactly one string "
            "argument.");
    return (-1);
  }

  if (ci->children_num < 1) {
    WARNING("threshold values: The `Type' block needs at least one option.");
    return (-1);
  }

  memcpy(&th, th_orig, sizeof(th));
  sstrncpy(th.type, ci->values[0].value.string, sizeof(th.type));

  th.warning_min = NAN;
  th.warning_max = NAN;
  th.failure_min = NAN;
  th.failure_max = NAN;
  th.hits = 0;
  th.hysteresis = 0;
  th.flags = UT_FLAG_INTERESTING; /* interesting by default */

  for (int i = 0; i < ci->children_num; i++) {
    oconfig_item_t *option = ci->children + i;

    if (strcasecmp("Instance", option->key) == 0)
      status = ut_config_type_instance(&th, option);
    else if (strcasecmp("DataSource", option->key) == 0)
      status = ut_config_type_datasource(&th, option);
    else if ((strcasecmp("WarningMax", option->key) == 0) ||
             (strcasecmp("FailureMax", option->key) == 0))
      status = ut_config_type_max(&th, option);
    else if ((strcasecmp("WarningMin", option->key) == 0) ||
             (strcasecmp("FailureMin", option->key) == 0))
      status = ut_config_type_min(&th, option);
    else if (strcasecmp("Interesting", option->key) == 0)
      status = cf_util_get_flag(option, &th.flags, UT_FLAG_INTERESTING);
    else if (strcasecmp("Invert", option->key) == 0)
      status = cf_util_get_flag(option, &th.flags, UT_FLAG_INVERT);
    else if (strcasecmp("Persist", option->key) == 0)
      status = cf_util_get_flag(option, &th.flags, UT_FLAG_PERSIST);
    else if (strcasecmp("PersistOK", option->key) == 0)
      status = cf_util_get_flag(option, &th.flags, UT_FLAG_PERSIST_OK);
    else if (strcasecmp("Percentage", option->key) == 0)
      status = cf_util_get_flag(option, &th.flags, UT_FLAG_PERCENTAGE);
    else if (strcasecmp("Hits", option->key) == 0)
      status = ut_config_type_hits(&th, option);
    else if (strcasecmp("Hysteresis", option->key) == 0)
      status = ut_config_type_hysteresis(&th, option);
    else {
      WARNING("threshold values: Option `%s' not allowed inside a `Type' "
              "block.",
              option->key);
      status = -1;
    }

    if (status != 0)
      break;
  }

  if (status == 0) {
    status = ut_threshold_add(&th);
  }

  return (status);
} /* int ut_config_type */
示例#3
0
文件: dbi.c 项目: Altiscale/collectd
static int cdbi_read_database_query (cdbi_database_t *db, /* {{{ */
    udb_query_t *q, udb_query_preparation_area_t *prep_area)
{
  const char *statement;
  dbi_result res;
  size_t column_num;
  char **column_names;
  char **column_values;
  int status;
  size_t i;

  /* Macro that cleans up dynamically allocated memory and returns the
   * specified status. */
#define BAIL_OUT(status) \
  if (column_names != NULL) { sfree (column_names[0]); sfree (column_names); } \
  if (column_values != NULL) { sfree (column_values[0]); sfree (column_values); } \
  if (res != NULL) { dbi_result_free (res); res = NULL; } \
  return (status)

  column_names = NULL;
  column_values = NULL;
  res = NULL;

  statement = udb_query_get_statement (q);
  assert (statement != NULL);

  res = dbi_conn_query (db->connection, statement);
  if (res == NULL)
  {
    char errbuf[1024];
    ERROR ("dbi plugin: cdbi_read_database_query (%s, %s): "
        "dbi_conn_query failed: %s",
        db->name, udb_query_get_name (q),
        cdbi_strerror (db->connection, errbuf, sizeof (errbuf)));
    BAIL_OUT (-1);
  }
  else /* Get the number of columns */
  {
    unsigned int db_status;

    db_status = dbi_result_get_numfields (res);
    if (db_status == DBI_FIELD_ERROR)
    {
      char errbuf[1024];
      ERROR ("dbi plugin: cdbi_read_database_query (%s, %s): "
          "dbi_result_get_numfields failed: %s",
          db->name, udb_query_get_name (q),
          cdbi_strerror (db->connection, errbuf, sizeof (errbuf)));
      BAIL_OUT (-1);
    }

    column_num = (size_t) db_status;
    DEBUG ("cdbi_read_database_query (%s, %s): There are %zu columns.",
        db->name, udb_query_get_name (q), column_num);
  }

  /* Allocate `column_names' and `column_values'. {{{ */
  column_names = (char **) calloc (column_num, sizeof (char *));
  if (column_names == NULL)
  {
    ERROR ("dbi plugin: malloc failed.");
    BAIL_OUT (-1);
  }

  column_names[0] = (char *) calloc (column_num,
      DATA_MAX_NAME_LEN * sizeof (char));
  if (column_names[0] == NULL)
  {
    ERROR ("dbi plugin: malloc failed.");
    BAIL_OUT (-1);
  }
  for (i = 1; i < column_num; i++)
    column_names[i] = column_names[i - 1] + DATA_MAX_NAME_LEN;

  column_values = (char **) calloc (column_num, sizeof (char *));
  if (column_values == NULL)
  {
    ERROR ("dbi plugin: malloc failed.");
    BAIL_OUT (-1);
  }

  column_values[0] = (char *) calloc (column_num,
      DATA_MAX_NAME_LEN * sizeof (char));
  if (column_values[0] == NULL)
  {
    ERROR ("dbi plugin: malloc failed.");
    BAIL_OUT (-1);
  }
  for (i = 1; i < column_num; i++)
    column_values[i] = column_values[i - 1] + DATA_MAX_NAME_LEN;
  /* }}} */

  /* Copy the field names to `column_names' */
  for (i = 0; i < column_num; i++) /* {{{ */
  {
    const char *column_name;

    column_name = dbi_result_get_field_name (res, (unsigned int) (i + 1));
    if (column_name == NULL)
    {
      ERROR ("dbi plugin: cdbi_read_database_query (%s, %s): "
          "Cannot retrieve name of field %zu.",
          db->name, udb_query_get_name (q), i + 1);
      BAIL_OUT (-1);
    }

    sstrncpy (column_names[i], column_name, DATA_MAX_NAME_LEN);
  } /* }}} for (i = 0; i < column_num; i++) */

  udb_query_prepare_result (q, prep_area, (db->host ? db->host : hostname_g),
      /* plugin = */ "dbi", db->name,
      column_names, column_num, /* interval = */ 0);

  /* 0 = error; 1 = success; */
  status = dbi_result_first_row (res); /* {{{ */
  if (status != 1)
  {
    char errbuf[1024];
    ERROR ("dbi plugin: cdbi_read_database_query (%s, %s): "
        "dbi_result_first_row failed: %s. Maybe the statement didn't "
        "return any rows?",
        db->name, udb_query_get_name (q),
        cdbi_strerror (db->connection, errbuf, sizeof (errbuf)));
    udb_query_finish_result (q, prep_area);
    BAIL_OUT (-1);
  } /* }}} */

  /* Iterate over all rows and call `udb_query_handle_result' with each list of
   * values. */
  while (42) /* {{{ */
  {
    status = 0;
    /* Copy the value of the columns to `column_values' */
    for (i = 0; i < column_num; i++) /* {{{ */
    {
      status = cdbi_result_get_field (res, (unsigned int) (i + 1),
          column_values[i], DATA_MAX_NAME_LEN);

      if (status != 0)
      {
        ERROR ("dbi plugin: cdbi_read_database_query (%s, %s): "
            "cdbi_result_get_field (%zu) failed.",
            db->name, udb_query_get_name (q), i + 1);
        status = -1;
        break;
      }
    } /* }}} for (i = 0; i < column_num; i++) */

    /* If all values were copied successfully, call `udb_query_handle_result'
     * to dispatch the row to the daemon. */
    if (status == 0) /* {{{ */
    {
      status = udb_query_handle_result (q, prep_area, column_values);
      if (status != 0)
      {
        ERROR ("dbi plugin: cdbi_read_database_query (%s, %s): "
            "udb_query_handle_result failed.",
            db->name, udb_query_get_name (q));
      }
    } /* }}} */

    /* Get the next row from the database. */
    status = dbi_result_next_row (res); /* {{{ */
    if (status != 1)
    {
      if (dbi_conn_error (db->connection, NULL) != 0)
      {
        char errbuf[1024];
        WARNING ("dbi plugin: cdbi_read_database_query (%s, %s): "
            "dbi_result_next_row failed: %s.",
            db->name, udb_query_get_name (q),
            cdbi_strerror (db->connection, errbuf, sizeof (errbuf)));
      }
      break;
    } /* }}} */
  } /* }}} while (42) */

  /* Tell the db query interface that we're done with this query. */
  udb_query_finish_result (q, prep_area);

  /* Clean up and return `status = 0' (success) */
  BAIL_OUT (0);
#undef BAIL_OUT
} /* }}} int cdbi_read_database_query */
示例#4
0
tinybool
verify_sdescriptions_mki (char *buf, char *mkiVal, u16 *mkiLen)
{

    char       *ptr,
               mkiValBuf[SDP_SRTP_MAX_MKI_SIZE_BYTES],
	       mkiLenBuf[MKI_BUF_LEN];
    int        idx = 0;
    unsigned long strtoul_result;
    char *strtoul_end;

    ptr = buf;
    /* MKI must begin with a digit */
    if (!ptr || (!isdigit((int) *ptr))) {
        return FALSE;
    }

    /* scan until we reach a non-digit or colon */
    while (*ptr) {
        if (*ptr == ':') {
	    /* terminate the MKI value */
	    mkiValBuf[idx] = 0;
	    ptr++;
	    break;
	} else if ((isdigit((int) *ptr) && (idx < SDP_SRTP_MAX_MKI_SIZE_BYTES-1))) {
	     mkiValBuf[idx++] = *ptr;
	} else {
	     return FALSE;
	}

	ptr++;
    }

    /* there has to be a mki length */
    if (*ptr == 0) {
        return FALSE;
    }

    idx = 0;

    /* verify the mki length (max 3 digits) */
    while (*ptr) {
        if (isdigit((int) *ptr) && (idx < 3)) {
	    mkiLenBuf[idx++] = *ptr;
	} else {
	    return FALSE;
	}

	ptr++;
    }

    mkiLenBuf[idx] = 0;

    errno = 0;
    strtoul_result = strtoul(mkiLenBuf, &strtoul_end, 10);

    /* mki len must be between 1..128 */
    if (errno || mkiLenBuf == strtoul_end || strtoul_result < 1 || strtoul_result > 128) {
      *mkiLen = 0;
      return FALSE;
    }

    *mkiLen = (u16) strtoul_result;
    sstrncpy(mkiVal, mkiValBuf, MKI_BUF_LEN);

    return TRUE;
}
示例#5
0
static riemann_event_t *
wrr_value_to_event(struct riemann_host const *host, /* {{{ */
                   data_set_t const *ds, value_list_t const *vl, size_t index,
                   gauge_t const *rates, int status) {
  riemann_event_t *event;
  char name_buffer[5 * DATA_MAX_NAME_LEN];
  char service_buffer[6 * DATA_MAX_NAME_LEN];
  size_t i;

  event = riemann_event_new();
  if (event == NULL) {
    ERROR("write_riemann plugin: riemann_event_new() failed.");
    return (NULL);
  }

  format_name(name_buffer, sizeof(name_buffer),
              /* host = */ "", vl->plugin, vl->plugin_instance, vl->type,
              vl->type_instance);
  if (host->always_append_ds || (ds->ds_num > 1)) {
    if (host->event_service_prefix == NULL)
      ssnprintf(service_buffer, sizeof(service_buffer), "%s/%s",
                &name_buffer[1], ds->ds[index].name);
    else
      ssnprintf(service_buffer, sizeof(service_buffer), "%s%s/%s",
                host->event_service_prefix, &name_buffer[1],
                ds->ds[index].name);
  } else {
    if (host->event_service_prefix == NULL)
      sstrncpy(service_buffer, &name_buffer[1], sizeof(service_buffer));
    else
      ssnprintf(service_buffer, sizeof(service_buffer), "%s%s",
                host->event_service_prefix, &name_buffer[1]);
  }

  riemann_event_set(
      event, RIEMANN_EVENT_FIELD_HOST, vl->host, RIEMANN_EVENT_FIELD_TIME,
      (int64_t)CDTIME_T_TO_TIME_T(vl->time), RIEMANN_EVENT_FIELD_TTL,
      (float)CDTIME_T_TO_DOUBLE(vl->interval) * host->ttl_factor,
      RIEMANN_EVENT_FIELD_STRING_ATTRIBUTES, "plugin", vl->plugin, "type",
      vl->type, "ds_name", ds->ds[index].name, NULL,
      RIEMANN_EVENT_FIELD_SERVICE, service_buffer, RIEMANN_EVENT_FIELD_NONE);

  if (host->check_thresholds) {
    const char *state = NULL;

    switch (status) {
    case STATE_OKAY:
      state = "ok";
      break;
    case STATE_ERROR:
      state = "critical";
      break;
    case STATE_WARNING:
      state = "warning";
      break;
    case STATE_MISSING:
      state = "unknown";
      break;
    }
    if (state)
      riemann_event_set(event, RIEMANN_EVENT_FIELD_STATE, state,
                        RIEMANN_EVENT_FIELD_NONE);
  }

  if (vl->plugin_instance[0] != 0)
    riemann_event_string_attribute_add(event, "plugin_instance",
                                       vl->plugin_instance);
  if (vl->type_instance[0] != 0)
    riemann_event_string_attribute_add(event, "type_instance",
                                       vl->type_instance);

  if ((ds->ds[index].type != DS_TYPE_GAUGE) && (rates != NULL)) {
    char ds_type[DATA_MAX_NAME_LEN];

    ssnprintf(ds_type, sizeof(ds_type), "%s:rate",
              DS_TYPE_TO_STRING(ds->ds[index].type));
    riemann_event_string_attribute_add(event, "ds_type", ds_type);
  } else {
    riemann_event_string_attribute_add(event, "ds_type",
                                       DS_TYPE_TO_STRING(ds->ds[index].type));
  }

  {
    char ds_index[DATA_MAX_NAME_LEN];

    ssnprintf(ds_index, sizeof(ds_index), "%zu", index);
    riemann_event_string_attribute_add(event, "ds_index", ds_index);
  }

  for (i = 0; i < riemann_attrs_num; i += 2)
    riemann_event_string_attribute_add(event, riemann_attrs[i],
                                       riemann_attrs[i + 1]);

  for (i = 0; i < riemann_tags_num; i++)
    riemann_event_tag_add(event, riemann_tags[i]);

  if (ds->ds[index].type == DS_TYPE_GAUGE) {
    riemann_event_set(event, RIEMANN_EVENT_FIELD_METRIC_D,
                      (double)vl->values[index].gauge,
                      RIEMANN_EVENT_FIELD_NONE);
  } else if (rates != NULL) {
    riemann_event_set(event, RIEMANN_EVENT_FIELD_METRIC_D, (double)rates[index],
                      RIEMANN_EVENT_FIELD_NONE);
  } else {
    int64_t metric;

    if (ds->ds[index].type == DS_TYPE_DERIVE)
      metric = (int64_t)vl->values[index].derive;
    else if (ds->ds[index].type == DS_TYPE_ABSOLUTE)
      metric = (int64_t)vl->values[index].absolute;
    else
      metric = (int64_t)vl->values[index].counter;

    riemann_event_set(event, RIEMANN_EVENT_FIELD_METRIC_S64, (int64_t)metric,
                      RIEMANN_EVENT_FIELD_NONE);
  }

  DEBUG("write_riemann plugin: Successfully created message for metric: "
        "host = \"%s\", service = \"%s\"",
        event->host, event->service);
  return (event);
} /* }}} riemann_event_t *wrr_value_to_event */
示例#6
0
/*
 * Functions
 */
static int us_open_socket (void)
{
	struct sockaddr_un sa = { 0 };
	int status;

	sock_fd = socket (PF_UNIX, SOCK_STREAM, 0);
	if (sock_fd < 0)
	{
		char errbuf[1024];
		ERROR ("unixsock plugin: socket failed: %s",
				sstrerror (errno, errbuf, sizeof (errbuf)));
		return (-1);
	}

	sa.sun_family = AF_UNIX;
	sstrncpy (sa.sun_path, (sock_file != NULL) ? sock_file : US_DEFAULT_PATH,
			sizeof (sa.sun_path));

	DEBUG ("unixsock plugin: socket path = %s", sa.sun_path);

	if (delete_socket)
	{
		errno = 0;
		status = unlink (sa.sun_path);
		if ((status != 0) && (errno != ENOENT))
		{
			char errbuf[1024];
			WARNING ("unixsock plugin: Deleting socket file \"%s\" failed: %s",
					sa.sun_path,
					sstrerror (errno, errbuf, sizeof (errbuf)));
		}
		else if (status == 0)
		{
			INFO ("unixsock plugin: Successfully deleted socket file \"%s\".",
					sa.sun_path);
		}
	}

	status = bind (sock_fd, (struct sockaddr *) &sa, sizeof (sa));
	if (status != 0)
	{
		char errbuf[1024];
		sstrerror (errno, errbuf, sizeof (errbuf));
		ERROR ("unixsock plugin: bind failed: %s", errbuf);
		close (sock_fd);
		sock_fd = -1;
		return (-1);
	}

	status = chmod (sa.sun_path, sock_perms);
	if (status == -1)
	{
		char errbuf[1024];
		ERROR ("unixsock plugin: chmod failed: %s",
				sstrerror (errno, errbuf, sizeof (errbuf)));
		close (sock_fd);
		sock_fd = -1;
		return (-1);
	}

	status = listen (sock_fd, 8);
	if (status != 0)
	{
		char errbuf[1024];
		ERROR ("unixsock plugin: listen failed: %s",
				sstrerror (errno, errbuf, sizeof (errbuf)));
		close (sock_fd);
		sock_fd = -1;
		return (-1);
	}

	do
	{
		const char *grpname;
		struct group *g;
		struct group sg;
		char grbuf[2048];

		grpname = (sock_group != NULL) ? sock_group : COLLECTD_GRP_NAME;
		g = NULL;

		status = getgrnam_r (grpname, &sg, grbuf, sizeof (grbuf), &g);
		if (status != 0)
		{
			char errbuf[1024];
			WARNING ("unixsock plugin: getgrnam_r (%s) failed: %s", grpname,
					sstrerror (errno, errbuf, sizeof (errbuf)));
			break;
		}
		if (g == NULL)
		{
			WARNING ("unixsock plugin: No such group: `%s'",
					grpname);
			break;
		}

		if (chown ((sock_file != NULL) ? sock_file : US_DEFAULT_PATH,
					(uid_t) -1, g->gr_gid) != 0)
		{
			char errbuf[1024];
			WARNING ("unixsock plugin: chown (%s, -1, %i) failed: %s",
					(sock_file != NULL) ? sock_file : US_DEFAULT_PATH,
					(int) g->gr_gid,
					sstrerror (errno, errbuf, sizeof (errbuf)));
		}
	} while (0);

	return (0);
} /* int us_open_socket */
示例#7
0
static int iptables_config (const char *key, const char *value)
{
	/* int ip_value; */
	protocol_version_t ip_version = 0;

	if (strcasecmp (key, "Chain") == 0)
		ip_version = IPV4;
	else if (strcasecmp (key, "Chain6") == 0)
		ip_version = IPV6;

	if (( ip_version == IPV4 ) || ( ip_version == IPV6 ))
	{
		ip_chain_t temp, *final, **list;
		char *table;
		int   table_len;
		char *chain;
		int   chain_len;

		char *value_copy;
		char *fields[4];
		int   fields_num;
		
		memset (&temp, 0, sizeof (temp));

		value_copy = strdup (value);
		if (value_copy == NULL)
		{
		    char errbuf[1024];
		    ERROR ("strdup failed: %s",
			    sstrerror (errno, errbuf, sizeof (errbuf)));
		    return (1);
		}

		/*
	         *  Time to fill the temp element
        	 *  Examine value string, it should look like:
	         *  Chain[6] <table> <chain> [<comment|num> [name]]
       		 */

		/* set IPv4 or IPv6 */
                temp.ip_version = ip_version;

		/* Chain <table> <chain> [<comment|num> [name]] */
		fields_num = strsplit (value_copy, fields, 4);
		if (fields_num < 2)
		{
		    free (value_copy);
		    return (1);
		}

		table = fields[0];
		chain = fields[1];

		table_len = strlen (table) + 1;
		if ((unsigned int)table_len > sizeof(temp.table))
		{
			ERROR ("Table `%s' too long.", table);
			free (value_copy);
			return (1);
		}
		sstrncpy (temp.table, table, table_len);

		chain_len = strlen (chain) + 1;
		if ((unsigned int)chain_len > sizeof(temp.chain))
		{
			ERROR ("Chain `%s' too long.", chain);
			free (value_copy);
			return (1);
		}
		sstrncpy (temp.chain, chain, chain_len);

		if (fields_num >= 3)
		{
		    char *comment = fields[2];
		    int   rule = atoi (comment);

		    if (rule)
		    {
			temp.rule.num = rule;
			temp.rule_type = RTYPE_NUM;
		    }
		    else
		    {
			temp.rule.comment = strdup (comment);
			if (temp.rule.comment == NULL)
			{
			    free (value_copy);
			    return (1);
			}
			temp.rule_type = RTYPE_COMMENT;
		    }
		}
		else
		{
		    temp.rule_type = RTYPE_COMMENT_ALL;
		}

		if (fields_num >= 4)
		    sstrncpy (temp.name, fields[3], sizeof (temp.name));

		free (value_copy);
		value_copy = NULL;
		table = NULL;
		chain = NULL;

		list = (ip_chain_t **) realloc (chain_list, (chain_num + 1) * sizeof (ip_chain_t *));
		if (list == NULL)
		{
		    char errbuf[1024];
		    ERROR ("realloc failed: %s",
			    sstrerror (errno, errbuf, sizeof (errbuf)));
		    return (1);
		}

		chain_list = list;
		final = (ip_chain_t *) malloc( sizeof(temp) );
示例#8
0
/*
 *  Function: get_state()
 *
 *  Parameters: request_id - unique id assigned by the platform to this subscription. Platform
 *                           uses this to track the status updates and to make subsequent termination
 *                           request.
 *              duration - how long the subscription is requested to be valid.
 *              watcher - entity that is requesting the presence state.
 *              presentity - entity whose presence state is requested.
 *              app_id - application that is making the subscription.
 *                       0: indicates call list blf application.
 *                       1..n: indicates the speeddial/blf associated with (1..n)th line button.
 *              feature_mask - indicates the additional features enabled.
 *
 *  Description:  is invoked by platform side whenever it needs to susbcribe
 *                for presence state of a presentity. This stores the susbcription
 *                data in a linked list and posts SIPSPI_EV_CC_SUBSCRIBE
 *                to SIP stack. We need to store the subscription data so that
 *                SUBSCRIBE response and NOTIFYs can be mapped to subscriptions.
 *
 *  Returns: void
 */
static void
get_state (int request_id,
           int duration,
           const char *watcher,
           const char *presentity,
           int app_id,
           int feature_mask)
{
    static const char fname[] = "get_state";
    pres_subscription_req_t *sub_req_p;

    DEF_DEBUG(DEB_F_PREFIX"REQ %d: TM %d: WTR %s: PRT %s: FMSK %d: APP %d\n",
         DEB_F_PREFIX_ARGS(BLF_INFO, fname),
         request_id, duration, watcher, presentity, feature_mask, app_id);
    /*
     * if there is no subscription list yet, create one.
     */
    if (s_pres_req_list == NULL) {
        s_pres_req_list = sll_create(find_matching_node);
        if (s_pres_req_list == NULL) {
            /* let platform know that we can not continue */
            ui_BLF_notification(request_id, CC_SIP_BLF_REJECTED, app_id);
            BLF_ERROR(MISC_F_PREFIX"Exiting : request list creation failed\n", fname);
            return;
        }
    }
    /*
     * check if a request is already created by walking through the list. if not, create one.
     */
    if ((sub_req_p = (pres_subscription_req_t *)
                sll_find(s_pres_req_list, &request_id)) == NULL) {
        /*
         * populate subscription request and append it to the list.
         */
        sub_req_p = (pres_subscription_req_t *)
            cpr_malloc(sizeof(pres_subscription_req_t));
        if (sub_req_p == NULL) {
            BLF_ERROR(MISC_F_PREFIX"Exiting : malloc failed\n", fname);
            return;
        }

        sub_req_p->request_id = request_id;
        sub_req_p->sub_id = CCSIP_SUBS_INVALID_SUB_ID;
        sub_req_p->highest_cseq = 0;
        sub_req_p->duration = duration;
        sstrncpy(sub_req_p->presentity, presentity, CC_MAX_DIALSTRING_LEN);
        sstrncpy(sub_req_p->watcher, watcher, CC_MAX_DIALSTRING_LEN);
        sub_req_p->app_id = app_id;
        sub_req_p->feature_mask = feature_mask;
        sub_req_p->blf_state = CC_SIP_BLF_UNKNOWN;

        (void) sll_append(s_pres_req_list, sub_req_p);
    } else { /* already exists. just update the duration */
        sub_req_p->duration = duration;
    }

    /*
     * post SIPSPI_EV_CC_SUBSCRIBE to SIP stack
     */
    if (send_subscribe_ev_to_sip_task(sub_req_p) != CC_RC_SUCCESS) {
        /*
         * remove the node from the list of subscriptions.
         */
        free_sub_request(sub_req_p);
        /* let platform know that we can not continue */
        ui_BLF_notification(request_id, CC_SIP_BLF_REJECTED, app_id);
        BLF_ERROR(MISC_F_PREFIX"Exiting : Unable to send SUBSCRIBE\n", fname);
        return;
    }

    BLF_DEBUG(DEB_F_PREFIX"Exiting : request made successfully\n", DEB_F_PREFIX_ARGS(BLF, fname));
    return;
}
示例#9
0
static int cj_config_add_key (cj_t *db, /* {{{ */
                                   oconfig_item_t *ci)
{
  cj_key_t *key;
  int status;
  int i;

  if ((ci->values_num != 1)
      || (ci->values[0].type != OCONFIG_TYPE_STRING))
  {
    WARNING ("curl_json plugin: The `Key' block "
             "needs exactly one string argument.");
    return (-1);
  }

  key = (cj_key_t *) malloc (sizeof (*key));
  if (key == NULL)
  {
    ERROR ("curl_json plugin: malloc failed.");
    return (-1);
  }
  memset (key, 0, sizeof (*key));
  key->magic = CJ_KEY_MAGIC;

  if (strcasecmp ("Key", ci->key) == 0)
  {
    status = cf_util_get_string (ci, &key->path);
    if (status != 0)
    {
      sfree (key);
      return (status);
    }
  }
  else
  {
    ERROR ("curl_json plugin: cj_config: "
           "Invalid key: %s", ci->key);
    return (-1);
  }

  status = 0;
  for (i = 0; i < ci->children_num; i++)
  {
    oconfig_item_t *child = ci->children + i;

    if (strcasecmp ("Type", child->key) == 0)
      status = cf_util_get_string (child, &key->type);
    else if (strcasecmp ("Instance", child->key) == 0)
      status = cf_util_get_string (child, &key->instance);
    else
    {
      WARNING ("curl_json plugin: Option `%s' not allowed here.", child->key);
      status = -1;
    }

    if (status != 0)
      break;
  } /* for (i = 0; i < ci->children_num; i++) */

  while (status == 0)
  {
    if (key->type == NULL)
    {
      WARNING ("curl_json plugin: `Type' missing in `Key' block.");
      status = -1;
    }

    break;
  } /* while (status == 0) */

  /* store path in a tree that will match the json map structure, example:
   * "httpd/requests/count",
   * "httpd/requests/current" ->
   * { "httpd": { "requests": { "count": $key, "current": $key } } }
   */
  if (status == 0)
  {
    char *ptr;
    char *name;
    char ent[PATH_MAX];
    c_avl_tree_t *tree;

    if (db->tree == NULL)
      db->tree = cj_avl_create();

    tree = db->tree;
    name = key->path;
    ptr = key->path;
    if (*ptr == '/')
      ++ptr;

    name = ptr;
    while (*ptr)
    {
      if (*ptr == '/')
      {
        c_avl_tree_t *value;
        int len;

        len = ptr-name;
        if (len == 0)
          break;
        sstrncpy (ent, name, len+1);

        if (c_avl_get (tree, ent, (void *) &value) != 0)
        {
          value = cj_avl_create ();
          c_avl_insert (tree, strdup (ent), value);
        }

        tree = value;
        name = ptr+1;
      }
      ++ptr;
    }
    if (*name)
      c_avl_insert (tree, strdup(name), key);
    else
    {
      ERROR ("curl_json plugin: invalid key: %s", key->path);
      status = -1;
    }
  }

  return (status);
} /* }}} int cj_config_add_key */
示例#10
0
文件: mailcap.c 项目: mavit/alpine
/*
 * mc_cmd_bldr - construct a command string to execute
 *
 *    If tmp_file is null, then the contents of the given MIME segment
 *    is not provided.  This is useful for building the "test=" string
 *    as it doesn't operate on the segment's data.
 *
 *    The return value is an alloc'd copy of the command to be executed.
 */
char *
mc_cmd_bldr(char *controlstring, int type, char *subtype,
	    BODY *body, char *tmp_file, char **err)
{
    char        *from, *to, *s, *parm;
    int	         prefixed = 0, used_tmp_file = 0;

    dprint((8, "- mc_cmd_bldr -\n"));

    for(from = controlstring, to = tmp_20k_buf; *from; ++from){
	if(prefixed){			/* previous char was % */
	    prefixed = 0;
	    switch(*from){
	      case '%':			/* turned \% into this earlier */
		if(to-tmp_20k_buf < SIZEOF_20KBUF)
		  *to++ = '%';

		break;

	      case 's':			/* insert tmp_file name in cmd */
		if(tmp_file){
		    used_tmp_file = 1;
		    sstrncpy(&to, tmp_file, SIZEOF_20KBUF-(to-tmp_20k_buf));
		}
		else
		  dprint((1,
			     "mc_cmd_bldr: %%s in cmd but not supplied!\n"));

		break;

	      case 't':			/* insert MIME type/subtype */
		/* quote to prevent funny business */
		if(to-tmp_20k_buf < SIZEOF_20KBUF)
		  *to++ = '\'';

		sstrncpy(&to, body_type_names(type), SIZEOF_20KBUF-(to-tmp_20k_buf));

		if(to-tmp_20k_buf < SIZEOF_20KBUF)
		  *to++ = '/';

		sstrncpy(&to, subtype, SIZEOF_20KBUF-(to-tmp_20k_buf));

		if(to-tmp_20k_buf < SIZEOF_20KBUF)
		  *to++ = '\'';

		break;

	      case '{':			/* insert requested MIME param */
		if(F_OFF(F_DO_MAILCAP_PARAM_SUBST, ps_global)){
		    int save;

		    dprint((2, "mc_cmd_bldr: param subs %s\n",
			    from ? from : "?"));
		    if(err){
			if((s = strindex(from, '}')) != NULL){
			  save = *++s;
			  *s = '\0';
			}

			snprintf(tmp_20k_buf, SIZEOF_20KBUF,
			    "Mailcap: see hidden feature %.200s (%%%.200s)",
			    feature_list_name(F_DO_MAILCAP_PARAM_SUBST), from);
			*err = tmp_20k_buf;
			if(s)
			  *s = save;
		    }

		    return(NULL);
		}

		s = strindex(from, '}');
		if(!s){
		    q_status_message1(SM_ORDER, 0, 4,
    "Ignoring ill-formed parameter reference in mailcap file: %.200s", from);
		    break;
		}

		*s = '\0';
		++from;    /* from is the part inside the brackets now */

		parm = parameter_val(body ? body->parameter : NULL, from);

		dprint((9,
			   "mc_cmd_bldr: parameter %s = %s\n", 
			   from ? from : "?", parm ? parm : "(not found)"));

		/*
		 * Quote parameter values for /bin/sh.
		 * Put single quotes around the whole thing but every time
		 * there is an actual single quote put it outside of the
		 * single quotes with a backslash in front of it.  So the
		 * parameter value  fred's car
		 * turns into       'fred'\''s car'
		 */
		if(to-tmp_20k_buf < SIZEOF_20KBUF)
		  *to++ = '\'';  /* opening quote */
		  
		if(parm){
		    char *p;

		    /*
		     * Copy value, but quote single quotes for /bin/sh
		     * Backslash quote is ignored inside single quotes so
		     * have to put those outside of the single quotes.
		     * (The parm+1000 nonsense is to protect against
		     * malicious mail trying to overflow our buffer.)
		     *
		     * TCH - Change 2/8/1999
		     * Also quote the ` to prevent execution of arbitrary code
		     */
		    for(p = parm; *p && p < parm+1000; p++){
			if((*p == '\'') || (*p == '`')){
			    if(to-tmp_20k_buf+4 < SIZEOF_20KBUF){
				*to++ = '\'';  /* closing quote */
				*to++ = '\\';
				*to++ = *p;    /* quoted character */
				*to++ = '\'';  /* opening quote */
			    }
			}
			else if(to-tmp_20k_buf < SIZEOF_20KBUF)
			  *to++ = *p;
		    }

		    fs_give((void **) &parm);
		}

		if(to-tmp_20k_buf < SIZEOF_20KBUF)
		  *to++ = '\'';  /* closing quote for /bin/sh */

		*s = '}'; /* restore */
		from = s;
		break;

		/*
		 * %n and %F are used by metamail to support otherwise
		 * unrecognized multipart Content-Types.  Pine does
		 * not use these since we're only dealing with the individual
		 * parts at this point.
		 */
	      case 'n':
	      case 'F':  
	      default:  
		dprint((9, 
		   "Ignoring %s format code in mailcap file: %%%c\n",
		   (*from == 'n' || *from == 'F') ? "unimplemented"
						  : "unrecognized",
		   *from));
		break;
	    }
	}
	else if(*from == '%')		/* next char is special */
	  prefixed = 1;
	else if(to-tmp_20k_buf < SIZEOF_20KBUF)		/* regular character, just copy */
	  *to++ = *from;
    }

    if(to-tmp_20k_buf < SIZEOF_20KBUF)
      *to = '\0';

    tmp_20k_buf[SIZEOF_20KBUF-1] = '\0';

    /*
     * file not specified, redirect to stdin
     */
    if(!used_tmp_file && tmp_file)
      snprintf(to, SIZEOF_20KBUF-(to-tmp_20k_buf), MC_ADD_TMP, tmp_file);

    return(cpystr(tmp_20k_buf));
}
示例#11
0
static int gr_format_name (char *ret, int ret_len,
        value_list_t const *vl,
        char const *ds_name,
        char const *prefix,
        char const *postfix,
        char const escape_char,
        unsigned int flags)
{
    char n_host[DATA_MAX_NAME_LEN];
    char n_plugin[DATA_MAX_NAME_LEN];
    char n_plugin_instance[DATA_MAX_NAME_LEN];
    char n_type[DATA_MAX_NAME_LEN];
    char n_type_instance[DATA_MAX_NAME_LEN];

    char tmp_plugin[2 * DATA_MAX_NAME_LEN + 1];
    char tmp_type[2 * DATA_MAX_NAME_LEN + 1];

    if (prefix == NULL)
        prefix = "";

    if (postfix == NULL)
        postfix = "";

    gr_copy_escape_part (n_host, vl->host,
            sizeof (n_host), escape_char);
    gr_copy_escape_part (n_plugin, vl->plugin,
            sizeof (n_plugin), escape_char);
    gr_copy_escape_part (n_plugin_instance, vl->plugin_instance,
            sizeof (n_plugin_instance), escape_char);
    gr_copy_escape_part (n_type, vl->type,
            sizeof (n_type), escape_char);
    gr_copy_escape_part (n_type_instance, vl->type_instance,
            sizeof (n_type_instance), escape_char);

    if (n_plugin_instance[0] != '\0')
        ssnprintf (tmp_plugin, sizeof (tmp_plugin), "%s%c%s",
            n_plugin,
            (flags & GRAPHITE_SEPARATE_INSTANCES) ? '.' : '-',
            n_plugin_instance);
    else
        sstrncpy (tmp_plugin, n_plugin, sizeof (tmp_plugin));

    if (n_type_instance[0] != '\0')
    {
        if ((flags & GRAPHITE_DROP_DUPE_FIELDS) && strcmp(n_plugin, n_type) == 0)
            sstrncpy (tmp_type, n_type_instance, sizeof (tmp_type));
        else
            ssnprintf (tmp_type, sizeof (tmp_type), "%s%c%s",
                n_type,
                (flags & GRAPHITE_SEPARATE_INSTANCES) ? '.' : '-',
                n_type_instance);
    }
    else
        sstrncpy (tmp_type, n_type, sizeof (tmp_type));

    /* Assert always_append_ds -> ds_name */
    assert (!(flags & GRAPHITE_ALWAYS_APPEND_DS) || (ds_name != NULL));
    if (ds_name != NULL)
    {
        if ((flags & GRAPHITE_DROP_DUPE_FIELDS) && strcmp(tmp_plugin, tmp_type) == 0)
            ssnprintf (ret, ret_len, "%s%s%s.%s.%s",
                prefix, n_host, postfix, tmp_plugin, ds_name);
        else
            ssnprintf (ret, ret_len, "%s%s%s.%s.%s.%s",
                prefix, n_host, postfix, tmp_plugin, tmp_type, ds_name);
    }
    else
        ssnprintf (ret, ret_len, "%s%s%s.%s.%s",
            prefix, n_host, postfix, tmp_plugin, tmp_type);

    return (0);
}
示例#12
0
文件: ctrls.c 项目: flxflx/weasel
/* Initialize the Controls API. */
void init_ctrls(void) {
  struct stat st;
  int sockfd;
  struct sockaddr_un sockun;
  size_t socklen;
  char *sockpath = PR_RUN_DIR "/test.sock";

  if (ctrls_pool) {
    destroy_pool(ctrls_pool);
  }

  ctrls_pool = make_sub_pool(permanent_pool);
  pr_pool_tag(ctrls_pool, "Controls Pool");

  /* Make sure all of the lists are zero'd out. */
  ctrls_action_list = NULL;
  ctrls_active_list = NULL;
  ctrls_free_list = NULL;

   /* And that the lookup indices are (re)set as well... */
  action_lookup_next = NULL;
  action_lookup_action = NULL;
  action_lookup_module = NULL;

  /* Run-time check to find out whether this platform identifies a
   * Unix domain socket file descriptor via the S_ISFIFO macro, or
   * the S_ISSOCK macro.
   */

  sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
  if (sockfd < 0) {
    pr_log_pri(PR_LOG_DEBUG, "unable to create Unix domain socket: %s",
      strerror(errno));
    return;
  }

  memset(&sockun, 0, sizeof(sockun));
  sockun.sun_family = AF_UNIX;
  sstrncpy(sockun.sun_path, sockpath, strlen(sockpath) + 1);
  socklen = sizeof(struct sockaddr_un);

  if (bind(sockfd, (struct sockaddr *) &sockun, socklen) < 0) {
    pr_log_pri(PR_LOG_DEBUG,
      "unable to bind to Unix domain socket at '%s': %s",
      sockpath, strerror(errno));
    (void) close(sockfd);
    (void) unlink(sockpath);
    return;
  }

  if (fstat(sockfd, &st) < 0) {
    pr_log_pri(PR_LOG_DEBUG,
      "unable to stat Unix domain socket at '%s': %s",
      sockpath, strerror(errno));
    (void) close(sockfd);
    (void) unlink(sockpath);
    return;
  }

#ifdef S_ISFIFO
  pr_log_debug(DEBUG10, "testing Unix domain socket using S_ISFIFO");
  if (S_ISFIFO(st.st_mode)) {
    ctrls_use_isfifo = TRUE;
  }
#else
  pr_log_debug(DEBUG10, "cannot test Unix domain socket using S_ISFIFO: "
    "macro undefined");
#endif

#ifdef S_ISSOCK
  pr_log_debug(DEBUG10, "testing Unix domain socket using S_ISSOCK");
  if (S_ISSOCK(st.st_mode)) {
    ctrls_use_isfifo = FALSE;
  }
#else
  pr_log_debug(DEBUG10, "cannot test Unix domain socket using S_ISSOCK: "
    "macro undefined");
#endif

  pr_log_debug(DEBUG10, "using %s macro for Unix domain socket detection",
    ctrls_use_isfifo ? "S_ISFIFO" : "S_ISSOCK");

  (void) close(sockfd);
  (void) unlink(sockpath);
  return;
}
示例#13
0
static void dpdk_stats_resolve_cnt_type(char *cnt_type, size_t cnt_type_len,
                                        const char *cnt_name) {
  char *type_end;
  type_end = strrchr(cnt_name, '_');

  if ((type_end != NULL) && (strncmp(cnt_name, "rx_", strlen("rx_")) == 0)) {
    if (strstr(type_end, "bytes") != NULL) {
      sstrncpy(cnt_type, "if_rx_octets", cnt_type_len);
    } else if (strstr(type_end, "error") != NULL) {
      sstrncpy(cnt_type, "if_rx_errors", cnt_type_len);
    } else if (strstr(type_end, "dropped") != NULL) {
      sstrncpy(cnt_type, "if_rx_dropped", cnt_type_len);
    } else if (strstr(type_end, "packets") != NULL) {
      sstrncpy(cnt_type, "if_rx_packets", cnt_type_len);
    } else if (strstr(type_end, "_placement") != NULL) {
      sstrncpy(cnt_type, "if_rx_errors", cnt_type_len);
    } else if (strstr(type_end, "_buff") != NULL) {
      sstrncpy(cnt_type, "if_rx_errors", cnt_type_len);
    } else {
      /* Does not fit obvious type: use a more generic one */
      sstrncpy(cnt_type, "derive", cnt_type_len);
    }

  } else if ((type_end != NULL) &&
             (strncmp(cnt_name, "tx_", strlen("tx_"))) == 0) {
    if (strstr(type_end, "bytes") != NULL) {
      sstrncpy(cnt_type, "if_tx_octets", cnt_type_len);
    } else if (strstr(type_end, "error") != NULL) {
      sstrncpy(cnt_type, "if_tx_errors", cnt_type_len);
    } else if (strstr(type_end, "dropped") != NULL) {
      sstrncpy(cnt_type, "if_tx_dropped", cnt_type_len);
    } else if (strstr(type_end, "packets") != NULL) {
      sstrncpy(cnt_type, "if_tx_packets", cnt_type_len);
    } else {
      /* Does not fit obvious type: use a more generic one */
      sstrncpy(cnt_type, "derive", cnt_type_len);
    }
  } else if ((type_end != NULL) &&
             (strncmp(cnt_name, "flow_", strlen("flow_"))) == 0) {

    if (strstr(type_end, "_filters") != NULL) {
      sstrncpy(cnt_type, "operations", cnt_type_len);
    } else if (strstr(type_end, "error") != NULL)
      sstrncpy(cnt_type, "errors", cnt_type_len);

  } else if ((type_end != NULL) &&
             (strncmp(cnt_name, "mac_", strlen("mac_"))) == 0) {
    if (strstr(type_end, "error") != NULL) {
      sstrncpy(cnt_type, "errors", cnt_type_len);
    }
  } else {
    /* Does not fit obvious type, or strrchr error:
     *   use a more generic type */
    sstrncpy(cnt_type, "derive", cnt_type_len);
  }
}
示例#14
0
文件: mysql.c 项目: baloo/collectd
/* Configuration handling functions {{{
 *
 * <Plugin mysql>
 *   <Database "plugin_instance1">
 *     Host "localhost"
 *     Port 22000
 *     ...
 *   </Database>
 * </Plugin>
 */
static int mysql_config_database (oconfig_item_t *ci) /* {{{ */
{
	mysql_database_t *db;
	int status = 0;
	int i;

	if ((ci->values_num != 1)
	    || (ci->values[0].type != OCONFIG_TYPE_STRING))
	{
		WARNING ("mysql plugin: The `Database' block "
			 "needs exactly one string argument.");
		return (-1);
	}

	db = (mysql_database_t *) malloc (sizeof (*db));
	if (db == NULL)
	{
		ERROR ("mysql plugin: malloc failed.");
		return (-1);
	}
	memset (db, 0, sizeof (*db));

	/* initialize all the pointers */
	db->alias    = NULL;
	db->host     = NULL;
	db->user     = NULL;
	db->pass     = NULL;
	db->database = NULL;
	db->socket   = NULL;
	db->con      = NULL;
	db->timeout  = 0;

	/* trigger a notification, if it's not running */
	db->slave_io_running  = 1;
	db->slave_sql_running = 1;

	status = cf_util_get_string (ci, &db->instance);
	if (status != 0)
	{
		sfree (db);
		return (status);
	}
	assert (db->instance != NULL);

	/* Fill the `mysql_database_t' structure.. */
	for (i = 0; i < ci->children_num; i++)
	{
		oconfig_item_t *child = ci->children + i;

		if (strcasecmp ("Alias", child->key) == 0)
			status = cf_util_get_string (child, &db->alias);
		else if (strcasecmp ("Host", child->key) == 0)
			status = cf_util_get_string (child, &db->host);
		else if (strcasecmp ("User", child->key) == 0)
			status = cf_util_get_string (child, &db->user);
		else if (strcasecmp ("Password", child->key) == 0)
			status = cf_util_get_string (child, &db->pass);
		else if (strcasecmp ("Port", child->key) == 0)
		{
			status = cf_util_get_port_number (child);
			if (status > 0)
			{
				db->port = status;
				status = 0;
			}
		}
		else if (strcasecmp ("Socket", child->key) == 0)
			status = cf_util_get_string (child, &db->socket);
		else if (strcasecmp ("Database", child->key) == 0)
			status = cf_util_get_string (child, &db->database);
		else if (strcasecmp ("ConnectTimeout", child->key) == 0)
			status = cf_util_get_int (child, &db->timeout);
		else if (strcasecmp ("MasterStats", child->key) == 0)
			status = cf_util_get_boolean (child, &db->master_stats);
		else if (strcasecmp ("SlaveStats", child->key) == 0)
			status = cf_util_get_boolean (child, &db->slave_stats);
		else if (strcasecmp ("SlaveNotifications", child->key) == 0)
			status = cf_util_get_boolean (child, &db->slave_notif);
		else if (strcasecmp ("InnodbStats", child->key) == 0)
			status = cf_util_get_boolean (child, &db->innodb_stats);
		else
		{
			WARNING ("mysql plugin: Option `%s' not allowed here.", child->key);
			status = -1;
		}

		if (status != 0)
			break;
	}

	/* If all went well, register this database for reading */
	if (status == 0)
	{
		user_data_t ud;
		char cb_name[DATA_MAX_NAME_LEN];

		DEBUG ("mysql plugin: Registering new read callback: %s",
				(db->database != NULL) ? db->database : "<default>");

		memset (&ud, 0, sizeof (ud));
		ud.data = (void *) db;
		ud.free_func = mysql_database_free;

		if (db->instance != NULL)
			ssnprintf (cb_name, sizeof (cb_name), "mysql-%s",
					db->instance);
		else
			sstrncpy (cb_name, "mysql", sizeof (cb_name));

		plugin_register_complex_read (/* group = */ NULL, cb_name,
					      mysql_read,
					      /* interval = */ 0, &ud);
	}
	else
	{
		mysql_database_free (db);
		return (-1);
	}

	return (0);
} /* }}} int mysql_config_database */
/**
 * Start the timer service loop.
 * Service loop waits for timer commands from timer clients processes them.
 * Waiting is done by issuing a select call with a timeout. This is the main
 * function that implements the timer functionality using the select call.
 * timeout value = duration on the head of the timer list.
 * @return CPR_SUCCESS or CPR_FAILURE
 */
cprRC_t start_timer_service_loop (void)
{
    static const char fname[] = "start_timer_service_loop";
    int lsock = -1;
    struct timeval tv;
    int ret;
    boolean use_timeout;


    /*
     * init mutex and cond var.
     * these are used for making API synchronous etc..
     */
    if (pthread_mutex_init(&api_mutex, NULL) != 0) {
        CPR_ERROR("%s: failed to initialize api_mutex err=%s\n", fname,
                  strerror(errno));
        return CPR_FAILURE;
    }
    
     
    /* open a unix datagram socket for client library */
    client_sock = socket(AF_LOCAL, SOCK_DGRAM, 0);
    if (client_sock == INVALID_SOCKET) {
        CPR_ERROR("%s:could not create client socket error=%s\n", fname, strerror(errno));
        return CPR_FAILURE;
    }

    /* bind service name to the socket */
    if (local_bind(client_sock,CLIENT_PATH) < 0) {
        CPR_ERROR("%s:could not bind local socket:error=%s\n", fname, strerror(errno));
        (void) close(client_sock);
        client_sock = INVALID_SOCKET;
        return CPR_FAILURE;
    }

    /* open another unix datagram socket for timer service */
    serv_sock = socket(AF_LOCAL, SOCK_DGRAM, 0);
    if (serv_sock == INVALID_SOCKET) {
        CPR_ERROR("%s:could not create server socket error=%s\n", fname, strerror(errno));
        serv_sock = INVALID_SOCKET;
        close(client_sock);
        client_sock = INVALID_SOCKET;
        return CPR_FAILURE;
    }

    if (local_bind(serv_sock, SERVER_PATH) < 0) {
        CPR_ERROR("%s:could not bind serv socket:error=%s\n", fname, strerror(errno));
        (void) close(serv_sock);
        (void) close(client_sock);
        client_sock = serv_sock = INVALID_SOCKET;
        return CPR_FAILURE;
    }

    /* initialize server and client addresses used for sending.*/
    bzero(&tmr_serv_addr, sizeof(tmr_serv_addr));
    tmr_serv_addr.sun_family = AF_LOCAL;
    sstrncpy(tmr_serv_addr.sun_path, SERVER_PATH, sizeof(tmr_serv_addr.sun_path));

    bzero(&tmr_client_addr, sizeof(tmr_client_addr));
    tmr_client_addr.sun_family = AF_LOCAL;
    sstrncpy(tmr_client_addr.sun_path, CLIENT_PATH, sizeof(tmr_client_addr.sun_path));

    while (1) {

        lsock = select_sockets();

	/* set the timer equal to duration on head */
	if (timerListHead != NULL) {
            tv.tv_sec = (timerListHead->duration)/1000;
            tv.tv_usec = (timerListHead->duration%1000)*1000;
            //CPR_INFO("%s:time duration on head =%d sec:%d usec (or %d msec)\n",
            //       fname, tv.tv_sec, tv.tv_usec, 
            //       timerListHead->duration);
            use_timeout = TRUE;
	} else {
            //CPR_INFO("%s:no timer in the list.. will block until there is one\n",
            //       fname);
            use_timeout = FALSE;
	}

        ret = select(lsock + 1, &socks, NULL, NULL, (use_timeout == TRUE) ? &tv:NULL);
        
        if (ret == -1) {
            CPR_ERROR("%s:error in select err=%s\n", fname,
                      strerror(errno));
            return(CPR_FAILURE);
        } else if (ret == 0) {
            /*
             * this means the head timer has expired..there could be others
             */
            timerListHead->duration = 0;
            process_expired_timers();
        } else {
            
            if (FD_ISSET(serv_sock, &socks)) {
                //CPR_INFO("Got something on serv_sock..\n");
                /* first reduce the duration of the head by current run time */
                if (timerListHead != NULL) {
                    //CPR_INFO("set head duration to =%d prev was= %d\n",
                    //       tv.tv_sec * 1000 + (tv.tv_usec/1000),
                    //       timerListHead->duration);
                    /* set the head with the remaining duration(tv) as indicated by select */
                    timerListHead->duration = tv.tv_sec * 1000 + (tv.tv_usec/1000);
                }  
                /* read the ipc message to remove or add a timer */
                (void) read_timer_cmd();
            }
	}
    }

}
示例#16
0
文件: mysql.c 项目: baloo/collectd
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 = 1;
		}
	}

	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 */
示例#17
0
文件: redis.c 项目: brd/collectd
static int redis_config_node (oconfig_item_t *ci) /* {{{ */
{
  redis_query_t *rq;
  int status;
  int timeout;

  redis_node_t rn = {
    .port = REDIS_DEF_PORT,
    .timeout.tv_usec = REDIS_DEF_TIMEOUT
  };

  sstrncpy (rn.host, REDIS_DEF_HOST, sizeof (rn.host));

  status = cf_util_get_string_buffer (ci, rn.name, sizeof (rn.name));
  if (status != 0)
    return (status);

  for (int i = 0; i < ci->children_num; i++)
  {
    oconfig_item_t *option = ci->children + i;

    if (strcasecmp ("Host", option->key) == 0)
      status = cf_util_get_string_buffer (option, rn.host, sizeof (rn.host));
    else if (strcasecmp ("Port", option->key) == 0)
    {
      status = cf_util_get_port_number (option);
      if (status > 0)
      {
        rn.port = status;
        status = 0;
      }
    }
    else if (strcasecmp ("Query", option->key) == 0)
    {
      rq = redis_config_query(option);
      if (rq == NULL) {
          status =1;
      } else {
          rq->next = rn.queries;
          rn.queries = rq;
      }
    }
    else if (strcasecmp ("Timeout", option->key) == 0)
    {
      status = cf_util_get_int (option, &timeout);
      if (status == 0) rn.timeout.tv_usec = timeout;
    }
    else if (strcasecmp ("Password", option->key) == 0)
      status = cf_util_get_string_buffer (option, rn.passwd, sizeof (rn.passwd));
    else
      WARNING ("redis plugin: Option `%s' not allowed inside a `Node' "
          "block. I'll ignore this option.", option->key);

    if (status != 0)
      break;
  }

  if (status != 0)
    return (status);

  return (redis_node_add (&rn));
} /* }}} int redis_config_node */

static int redis_config (oconfig_item_t *ci) /* {{{ */
{
  for (int i = 0; i < ci->children_num; i++)
  {
    oconfig_item_t *option = ci->children + i;

    if (strcasecmp ("Node", option->key) == 0)
      redis_config_node (option);
    else
      WARNING ("redis plugin: Option `%s' not allowed in redis"
          " configuration. It will be ignored.", option->key);
  }

  if (nodes_head == NULL)
  {
    ERROR ("redis plugin: No valid node configuration could be found.");
    return (ENOENT);
  }

  return (0);
} /* }}} */

  __attribute__ ((nonnull(2)))
static void redis_submit (char *plugin_instance,
    const char *type, const char *type_instance,
    value_t value) /* {{{ */
{
  value_t values[1];
  value_list_t vl = VALUE_LIST_INIT;

  values[0] = value;

  vl.values = values;
  vl.values_len = 1;
  sstrncpy (vl.host, hostname_g, sizeof (vl.host));
  sstrncpy (vl.plugin, "redis", sizeof (vl.plugin));
  if (plugin_instance != NULL)
    sstrncpy (vl.plugin_instance, plugin_instance,
        sizeof (vl.plugin_instance));
  sstrncpy (vl.type, type, sizeof (vl.type));
  if (type_instance != NULL)
    sstrncpy (vl.type_instance, type_instance,
        sizeof (vl.type_instance));

  plugin_dispatch_values (&vl);
} /* }}} */
示例#18
0
/* Must hold metrics_lock when calling this function. */
static int statsd_metric_submit_unsafe(char const *name,
                                       statsd_metric_t *metric) /* {{{ */
{
  value_list_t vl = VALUE_LIST_INIT;

  vl.values = &(value_t){.gauge = NAN};
  vl.values_len = 1;
  sstrncpy(vl.plugin, "statsd", sizeof(vl.plugin));

  if (metric->type == STATSD_GAUGE)
    sstrncpy(vl.type, "gauge", sizeof(vl.type));
  else if (metric->type == STATSD_TIMER)
    sstrncpy(vl.type, "latency", sizeof(vl.type));
  else if (metric->type == STATSD_SET)
    sstrncpy(vl.type, "objects", sizeof(vl.type));
  else /* if (metric->type == STATSD_COUNTER) */
    sstrncpy(vl.type, "derive", sizeof(vl.type));

  sstrncpy(vl.type_instance, name, sizeof(vl.type_instance));

  if (metric->type == STATSD_GAUGE)
    vl.values[0].gauge = (gauge_t)metric->value;
  else if (metric->type == STATSD_TIMER) {
    bool have_events = (metric->updates_num > 0);

    /* Make sure all timer metrics share the *same* timestamp. */
    vl.time = cdtime();

    snprintf(vl.type_instance, sizeof(vl.type_instance), "%s-average", name);
    vl.values[0].gauge =
        have_events
            ? CDTIME_T_TO_DOUBLE(latency_counter_get_average(metric->latency))
            : NAN;
    plugin_dispatch_values(&vl);

    if (conf_timer_lower) {
      snprintf(vl.type_instance, sizeof(vl.type_instance), "%s-lower", name);
      vl.values[0].gauge =
          have_events
              ? CDTIME_T_TO_DOUBLE(latency_counter_get_min(metric->latency))
              : NAN;
      plugin_dispatch_values(&vl);
    }

    if (conf_timer_upper) {
      snprintf(vl.type_instance, sizeof(vl.type_instance), "%s-upper", name);
      vl.values[0].gauge =
          have_events
              ? CDTIME_T_TO_DOUBLE(latency_counter_get_max(metric->latency))
              : NAN;
      plugin_dispatch_values(&vl);
    }

    if (conf_timer_sum) {
      snprintf(vl.type_instance, sizeof(vl.type_instance), "%s-sum", name);
      vl.values[0].gauge =
          have_events
              ? CDTIME_T_TO_DOUBLE(latency_counter_get_sum(metric->latency))
              : NAN;
      plugin_dispatch_values(&vl);
    }

    for (size_t i = 0; i < conf_timer_percentile_num; i++) {
      snprintf(vl.type_instance, sizeof(vl.type_instance), "%s-percentile-%.0f",
               name, conf_timer_percentile[i]);
      vl.values[0].gauge =
          have_events ? CDTIME_T_TO_DOUBLE(latency_counter_get_percentile(
                            metric->latency, conf_timer_percentile[i]))
                      : NAN;
      plugin_dispatch_values(&vl);
    }

    /* Keep this at the end, since vl.type is set to "gauge" here. The
     * vl.type's above are implicitly set to "latency". */
    if (conf_timer_count) {
      sstrncpy(vl.type, "gauge", sizeof(vl.type));
      snprintf(vl.type_instance, sizeof(vl.type_instance), "%s-count", name);
      vl.values[0].gauge = latency_counter_get_num(metric->latency);
      plugin_dispatch_values(&vl);
    }

    latency_counter_reset(metric->latency);
    return 0;
  } else if (metric->type == STATSD_SET) {
    if (metric->set == NULL)
      vl.values[0].gauge = 0.0;
    else
      vl.values[0].gauge = (gauge_t)c_avl_size(metric->set);
  } else { /* STATSD_COUNTER */
    gauge_t delta = nearbyint(metric->value);

    /* Etsy's statsd writes counters as two metrics: a rate and the change since
     * the last write. Since collectd does not reset its DERIVE metrics to zero,
     * this makes little sense, but we're dispatching a "count" metric here
     * anyway - if requested by the user - for compatibility reasons. */
    if (conf_counter_sum) {
      sstrncpy(vl.type, "count", sizeof(vl.type));
      vl.values[0].gauge = delta;
      plugin_dispatch_values(&vl);

      /* restore vl.type */
      sstrncpy(vl.type, "derive", sizeof(vl.type));
    }

    /* Rather than resetting value to zero, subtract delta so we correctly keep
     * track of residuals. */
    metric->value -= delta;
    metric->counter += (derive_t)delta;

    vl.values[0].derive = metric->counter;
  }

  return plugin_dispatch_values(&vl);
} /* }}} int statsd_metric_submit_unsafe */
示例#19
0
int handle_getthreshold (FILE *fh, char *buffer)
{
  char *command;
  char *identifier;
  char *identifier_copy;

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

  threshold_t threshold;

  int   status;
  size_t i;

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

  DEBUG ("utils_cmd_getthreshold: handle_getthreshold (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 ("GETTHRESHOLD", command) != 0)
  {
    print_to_socket (fh, "-1 Unexpected command: `%s'.\n", command);
    return (-1);
  }

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

  if (*buffer != 0)
  {
    print_to_socket (fh, "-1 Garbage after end of command: %s\n", buffer);
    return (-1);
  }

  /* parse_identifier() modifies its first argument,
   * returning pointers into it */
  identifier_copy = sstrdup (identifier);

  status = parse_identifier (identifier_copy, &host,
      &plugin, &plugin_instance,
      &type, &type_instance);
  if (status != 0)
  {
    DEBUG ("handle_getthreshold: Cannot parse identifier `%s'.", identifier);
    print_to_socket (fh, "-1 Cannot parse identifier `%s'.\n", identifier);
    sfree (identifier_copy);
    return (-1);
  }

  value_list_t vl = {
    .values = NULL
  };
  sstrncpy (vl.host, host, sizeof (vl.host));
  sstrncpy (vl.plugin, plugin, sizeof (vl.plugin));
  if (plugin_instance != NULL)
    sstrncpy (vl.plugin_instance, plugin_instance, sizeof (vl.plugin_instance));
  sstrncpy (vl.type, type, sizeof (vl.type));
  if (type_instance != NULL)
    sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance));
  sfree (identifier_copy);

  status = ut_search_threshold (&vl, &threshold);
  if (status == ENOENT)
  {
    print_to_socket (fh, "-1 No threshold found for identifier %s\n",
        identifier);
    return (0);
  }
  else if (status != 0)
  {
    print_to_socket (fh, "-1 Error while looking up threshold: %i\n",
        status);
    return (-1);
  }

  /* Lets count the number of lines we'll return. */
  i = 0;
  if (threshold.host[0] != 0)            i++;
  if (threshold.plugin[0] != 0)          i++;
  if (threshold.plugin_instance[0] != 0) i++;
  if (threshold.type[0] != 0)            i++;
  if (threshold.type_instance[0] != 0)   i++;
  if (threshold.data_source[0] != 0)     i++;
  if (!isnan (threshold.warning_min))    i++;
  if (!isnan (threshold.warning_max))    i++;
  if (!isnan (threshold.failure_min))    i++;
  if (!isnan (threshold.failure_max))    i++;
  if (threshold.hysteresis > 0.0)        i++;
  if (threshold.hits > 1)                i++;

  /* Print the response */
  print_to_socket (fh, "%zu Threshold found\n", i);

  if (threshold.host[0] != 0)
    print_to_socket (fh, "Host: %s\n", threshold.host)
  if (threshold.plugin[0] != 0)
    print_to_socket (fh, "Plugin: %s\n", threshold.plugin)
  if (threshold.plugin_instance[0] != 0)
    print_to_socket (fh, "Plugin Instance: %s\n", threshold.plugin_instance)
  if (threshold.type[0] != 0)
    print_to_socket (fh, "Type: %s\n", threshold.type)
  if (threshold.type_instance[0] != 0)
    print_to_socket (fh, "Type Instance: %s\n", threshold.type_instance)
  if (threshold.data_source[0] != 0)
    print_to_socket (fh, "Data Source: %s\n", threshold.data_source)
  if (!isnan (threshold.warning_min))
    print_to_socket (fh, "Warning Min: %g\n", threshold.warning_min)
  if (!isnan (threshold.warning_max))
    print_to_socket (fh, "Warning Max: %g\n", threshold.warning_max)
  if (!isnan (threshold.failure_min))
    print_to_socket (fh, "Failure Min: %g\n", threshold.failure_min)
  if (!isnan (threshold.failure_max))
    print_to_socket (fh, "Failure Max: %g\n", threshold.failure_max)
  if (threshold.hysteresis > 0.0)
    print_to_socket (fh, "Hysteresis: %g\n", threshold.hysteresis)
  if (threshold.hits > 1)
    print_to_socket (fh, "Hits: %i\n", threshold.hits)

  return (0);
} /* int handle_getthreshold */
示例#20
0
static void *us_handle_client (void *arg)
{
	int fdin;
	int fdout;
	FILE *fhin, *fhout;

	fdin = *((int *) arg);
	free (arg);
	arg = NULL;

	DEBUG ("unixsock plugin: us_handle_client: Reading from fd #%i", fdin);

	fdout = dup (fdin);
	if (fdout < 0)
	{
		char errbuf[1024];
		ERROR ("unixsock plugin: dup failed: %s",
				sstrerror (errno, errbuf, sizeof (errbuf)));
		close (fdin);
		pthread_exit ((void *) 1);
	}

	fhin  = fdopen (fdin, "r");
	if (fhin == NULL)
	{
		char errbuf[1024];
		ERROR ("unixsock plugin: fdopen failed: %s",
				sstrerror (errno, errbuf, sizeof (errbuf)));
		close (fdin);
		close (fdout);
		pthread_exit ((void *) 1);
		return ((void *) 1);
	}

	fhout = fdopen (fdout, "w");
	if (fhout == NULL)
	{
		char errbuf[1024];
		ERROR ("unixsock plugin: fdopen failed: %s",
				sstrerror (errno, errbuf, sizeof (errbuf)));
		fclose (fhin); /* this closes fdin as well */
		close (fdout);
		pthread_exit ((void *) 1);
		return ((void *) 1);
	}

	/* change output buffer to line buffered mode */
	if (setvbuf (fhout, NULL, _IOLBF, 0) != 0)
	{
		char errbuf[1024];
		ERROR ("unixsock plugin: setvbuf failed: %s",
				sstrerror (errno, errbuf, sizeof (errbuf)));
		fclose (fhin);
		fclose (fhout);
		pthread_exit ((void *) 1);
		return ((void *) 0);
	}

	while (42)
	{
		char buffer[1024];
		char buffer_copy[1024];
		char *fields[128];
		int   fields_num;
		int   len;

		errno = 0;
		if (fgets (buffer, sizeof (buffer), fhin) == NULL)
		{
			if ((errno == EINTR) || (errno == EAGAIN))
				continue;

			if (errno != 0)
			{
				char errbuf[1024];
				WARNING ("unixsock plugin: failed to read from socket #%i: %s",
						fileno (fhin),
						sstrerror (errno, errbuf, sizeof (errbuf)));
			}
			break;
		}

		len = strlen (buffer);
		while ((len > 0)
				&& ((buffer[len - 1] == '\n') || (buffer[len - 1] == '\r')))
			buffer[--len] = '\0';

		if (len == 0)
			continue;

		sstrncpy (buffer_copy, buffer, sizeof (buffer_copy));

		fields_num = strsplit (buffer_copy, fields,
				sizeof (fields) / sizeof (fields[0]));
		if (fields_num < 1)
		{
			fprintf (fhout, "-1 Internal error\n");
			fclose (fhin);
			fclose (fhout);
			pthread_exit ((void *) 1);
			return ((void *) 1);
		}

		if (strcasecmp (fields[0], "getval") == 0)
		{
			handle_getval (fhout, buffer);
		}
		else if (strcasecmp (fields[0], "getthreshold") == 0)
		{
			handle_getthreshold (fhout, buffer);
		}
		else if (strcasecmp (fields[0], "putval") == 0)
		{
			handle_putval (fhout, buffer);
		}
		else if (strcasecmp (fields[0], "listval") == 0)
		{
			handle_listval (fhout, buffer);
		}
		else if (strcasecmp (fields[0], "putnotif") == 0)
		{
			handle_putnotif (fhout, buffer);
		}
		else if (strcasecmp (fields[0], "flush") == 0)
		{
			handle_flush (fhout, buffer);
		}
		else
		{
			if (fprintf (fhout, "-1 Unknown command: %s\n", fields[0]) < 0)
			{
				char errbuf[1024];
				WARNING ("unixsock plugin: failed to write to socket #%i: %s",
						fileno (fhout),
						sstrerror (errno, errbuf, sizeof (errbuf)));
				break;
			}
		}
	} /* while (fgets) */

	DEBUG ("unixsock plugin: us_handle_client: Exiting..");
	fclose (fhin);
	fclose (fhout);

	pthread_exit ((void *) 0);
	return ((void *) 0);
} /* void *us_handle_client */
示例#21
0
static int cx_handle_instance_xpath (xmlXPathContextPtr xpath_ctx, /* {{{ */
    cx_xpath_t *xpath, value_list_t *vl,
    _Bool is_table)
{
  xmlXPathObjectPtr instance_node_obj = NULL;
  xmlNodeSetPtr instance_node = NULL;

  memset (vl->type_instance, 0, sizeof (vl->type_instance));

  /* If the base xpath returns more than one block, the result is assumed to be
   * a table. The `Instance' option is not optional in this case. Check for the
   * condition and inform the user. */
  if (is_table)
  {
    WARNING ("curl_xml plugin: "
        "Base-XPath %s is a table (more than one result was returned), "
        "but no instance-XPath has been defined.",
        xpath->path);
    return (-1);
  }

  /* instance has to be an xpath expression */
  if (xpath->instance != NULL)
  {
    int tmp_size;

    instance_node_obj = cx_evaluate_xpath (xpath_ctx, BAD_CAST xpath->instance);
    if (instance_node_obj == NULL)
      return (-1); /* error is logged already */

    instance_node = instance_node_obj->nodesetval;
    tmp_size = (instance_node) ? instance_node->nodeNr : 0;

    if (tmp_size <= 0)
    {
      WARNING ("curl_xml plugin: "
          "relative xpath expression for 'InstanceFrom' \"%s\" doesn't match "
          "any of the nodes. Skipping the node.", xpath->instance);
      xmlXPathFreeObject (instance_node_obj);
      return (-1);
    }

    if (tmp_size > 1)
    {
      WARNING ("curl_xml plugin: "
          "relative xpath expression for 'InstanceFrom' \"%s\" is expected "
          "to return only one text node. Skipping the node.", xpath->instance);
      xmlXPathFreeObject (instance_node_obj);
      return (-1);
    }

    /* ignoring the element if other than textnode/attribute */
    if (cx_if_not_text_node(instance_node->nodeTab[0]))
    {
      WARNING ("curl_xml plugin: "
          "relative xpath expression \"%s\" is expected to return only text node "
          "which is not the case. Skipping the node.", xpath->instance);
      xmlXPathFreeObject (instance_node_obj);
      return (-1);
    }
  } /* if (xpath->instance != NULL) */

  if (xpath->instance_prefix != NULL)
  {
    if (instance_node != NULL)
      ssnprintf (vl->type_instance, sizeof (vl->type_instance),"%s%s",
          xpath->instance_prefix, (char *) xmlNodeGetContent(instance_node->nodeTab[0]));
    else
      sstrncpy (vl->type_instance, xpath->instance_prefix,
          sizeof (vl->type_instance));
  }
  else
  {
    /* If instance_prefix and instance_node are NULL, then
     * don't set the type_instance */
    if (instance_node != NULL)
      sstrncpy (vl->type_instance, (char *) xmlNodeGetContent(instance_node->nodeTab[0]),
          sizeof (vl->type_instance));
  }

  /* Free `instance_node_obj' this late, because `instance_node' points to
   * somewhere inside this structure. */
  xmlXPathFreeObject (instance_node_obj);

  return (0);
} /* }}} int cx_handle_instance_xpath */
示例#22
0
static void fscache_read_stats_file (FILE *fh)
{
    char section[DATA_MAX_NAME_LEN];
    size_t section_len;

    char linebuffer[BUFSIZE];

/*
 *  cat /proc/fs/fscache/stats
 *      FS-Cache statistics
 *      Cookies: idx=2 dat=0 spc=0
 *      Objects: alc=0 nal=0 avl=0 ded=0
 *      ChkAux : non=0 ok=0 upd=0 obs=0
 *      Pages  : mrk=0 unc=0
 *      Acquire: n=2 nul=0 noc=0 ok=2 nbf=0 oom=0
 *      Lookups: n=0 neg=0 pos=0 crt=0
 *      Updates: n=0 nul=0 run=0
 *      Relinqs: n=0 nul=0 wcr=0
 *      AttrChg: n=0 ok=0 nbf=0 oom=0 run=0
 *      Allocs : n=0 ok=0 wt=0 nbf=0
 *      Allocs : ops=0 owt=0
 *      Retrvls: n=0 ok=0 wt=0 nod=0 nbf=0 int=0 oom=0
 *      Retrvls: ops=0 owt=0
 *      Stores : n=0 ok=0 agn=0 nbf=0 oom=0
 *      Stores : ops=0 run=0
 *      Ops    : pend=0 run=0 enq=0
 *      Ops    : dfr=0 rel=0 gc=0
 */

    /* Read file line by line */
    while (fgets (linebuffer, sizeof (linebuffer), fh) != NULL)
    {
        char *lineptr;
        char *fields[32];
        int fields_num;
        int i;

        /* Find the colon and replace it with a null byte */
        lineptr = strchr (linebuffer, ':');
        if (lineptr == NULL)
            continue;
        *lineptr = 0;
        lineptr++;

        /* Copy and clean up the section name */
        sstrncpy (section, linebuffer, sizeof (section));
        section_len = strlen (section);
        while ((section_len > 0) && isspace ((int) section[section_len - 1]))
        {
            section_len--;
            section[section_len] = 0;
        }
        if (section_len == 0)
            continue;

        fields_num = strsplit (lineptr, fields, STATIC_ARRAY_SIZE (fields));
        if (fields_num <= 0)
            continue;

        for (i = 0; i < fields_num; i++)
        {
            char *field_name;
            char *field_value_str;
            value_t field_value_cnt;
            int status;

            field_name = fields[i];
            assert (field_name != NULL);

            field_value_str = strchr (field_name, '=');
            if (field_value_str == NULL)
                continue;
            *field_value_str = 0;
            field_value_str++;

            status = parse_value (field_value_str, &field_value_cnt,
                    DS_TYPE_DERIVE);
            if (status != 0)
                continue;

            fscache_submit (section, field_name, field_value_cnt);
        }
    } /* while (fgets) */
} /* void fscache_read_stats_file */
示例#23
0
static int  cx_handle_base_xpath (char const *plugin_instance, /* {{{ */
    char const *host,
    xmlXPathContextPtr xpath_ctx, const data_set_t *ds, 
    char *base_xpath, cx_xpath_t *xpath)
{
  int total_nodes;
  int i;

  xmlXPathObjectPtr base_node_obj = NULL;
  xmlNodeSetPtr base_nodes = NULL;

  value_list_t vl = VALUE_LIST_INIT;

  base_node_obj = cx_evaluate_xpath (xpath_ctx, BAD_CAST base_xpath); 
  if (base_node_obj == NULL)
    return -1; /* error is logged already */

  base_nodes = base_node_obj->nodesetval;
  total_nodes = (base_nodes) ? base_nodes->nodeNr : 0;

  if (total_nodes == 0)
  {
     ERROR ("curl_xml plugin: "
              "xpath expression \"%s\" doesn't match any of the nodes. "
              "Skipping the xpath block...", base_xpath);
     xmlXPathFreeObject (base_node_obj);
     return -1;
  }

  /* If base_xpath returned multiple results, then */
  /* Instance in the xpath block is required */ 
  if (total_nodes > 1 && xpath->instance == NULL)
  {
    ERROR ("curl_xml plugin: "
             "InstanceFrom is must in xpath block since the base xpath expression \"%s\" "
             "returned multiple results. Skipping the xpath block...", base_xpath);
    return -1;
  }

  /* set the values for the value_list */
  vl.values_len = ds->ds_num;
  sstrncpy (vl.type, xpath->type, sizeof (vl.type));
  sstrncpy (vl.plugin, "curl_xml", sizeof (vl.plugin));
  sstrncpy (vl.host, (host != NULL) ? host : hostname_g, sizeof (vl.host));
  if (plugin_instance != NULL)
    sstrncpy (vl.plugin_instance, plugin_instance, sizeof (vl.plugin_instance)); 

  for (i = 0; i < total_nodes; i++)
  {
    int status;

    xpath_ctx->node = base_nodes->nodeTab[i];

    status = cx_handle_instance_xpath (xpath_ctx, xpath, &vl,
        /* is_table = */ (total_nodes > 1));
    if (status != 0)
      continue; /* An error has already been reported. */

    status = cx_handle_all_value_xpaths (xpath_ctx, xpath, ds, &vl);
    if (status != 0)
      continue; /* An error has been logged. */
  } /* for (i = 0; i < total_nodes; i++) */

  /* free up the allocated memory */
  xmlXPathFreeObject (base_node_obj); 

  return (0); 
} /* }}} cx_handle_base_xpath */
示例#24
0
static int camqp_write (const data_set_t *ds, const value_list_t *vl, /* {{{ */
        user_data_t *user_data)
{
    camqp_config_t *conf = user_data->data;
    char routing_key[6 * DATA_MAX_NAME_LEN];
    char buffer[4096];
    int status;

    if ((ds == NULL) || (vl == NULL) || (conf == NULL))
        return (EINVAL);

    memset (buffer, 0, sizeof (buffer));

    if (conf->routing_key != NULL)
    {
        sstrncpy (routing_key, conf->routing_key, sizeof (routing_key));
    }
    else
    {
        size_t i;
        ssnprintf (routing_key, sizeof (routing_key), "collectd/%s/%s/%s/%s/%s",
                vl->host,
                vl->plugin, vl->plugin_instance,
                vl->type, vl->type_instance);

        /* Switch slashes (the only character forbidden by collectd) and dots
         * (the separation character used by AMQP). */
        for (i = 0; routing_key[i] != 0; i++)
        {
            if (routing_key[i] == '.')
                routing_key[i] = '/';
            else if (routing_key[i] == '/')
                routing_key[i] = '.';
        }
    }

    if (conf->format == CAMQP_FORMAT_COMMAND)
    {
        status = create_putval (buffer, sizeof (buffer), ds, vl);
        if (status != 0)
        {
            ERROR ("amqp plugin: create_putval failed with status %i.",
                    status);
            return (status);
        }
    }
    else if (conf->format == CAMQP_FORMAT_JSON)
    {
        size_t bfree = sizeof (buffer);
        size_t bfill = 0;

        format_json_initialize (buffer, &bfill, &bfree);
        format_json_value_list (buffer, &bfill, &bfree, ds, vl, conf->store_rates);
        format_json_finalize (buffer, &bfill, &bfree);
    }
    else
    {
        ERROR ("amqp plugin: Invalid format (%i).", conf->format);
        return (-1);
    }

    pthread_mutex_lock (&conf->lock);
    status = camqp_write_locked (conf, buffer, routing_key);
    pthread_mutex_unlock (&conf->lock);

    return (status);
} /* }}} int camqp_write */
示例#25
0
文件: snmp.c 项目: BrianB2/collectd
static int csnmp_dispatch_table (host_definition_t *host, data_definition_t *data,
    csnmp_list_instances_t *instance_list,
    csnmp_table_values_t **value_table)
{
  const data_set_t *ds;
  value_list_t vl = VALUE_LIST_INIT;

  csnmp_list_instances_t *instance_list_ptr;
  csnmp_table_values_t **value_table_ptr;

  int i;
  _Bool have_more;
  oid_t current_suffix;

  ds = plugin_get_ds (data->type);
  if (!ds)
  {
    ERROR ("snmp plugin: DataSet `%s' not defined.", data->type);
    return (-1);
  }
  assert (ds->ds_num == data->values_len);

  instance_list_ptr = instance_list;

  value_table_ptr = malloc (sizeof (*value_table_ptr) * data->values_len);
  if (value_table_ptr == NULL)
    return (-1);
  for (i = 0; i < data->values_len; i++)
    value_table_ptr[i] = value_table[i];

  vl.values_len = ds->ds_num;
  vl.values = malloc (sizeof (*vl.values) * vl.values_len);
  if (vl.values == NULL)
  {
    ERROR ("snmp plugin: malloc failed.");
    sfree (value_table_ptr);
    return (-1);
  }

  sstrncpy (vl.host, host->name, sizeof (vl.host));
  sstrncpy (vl.plugin, "snmp", sizeof (vl.plugin));

  vl.interval = host->interval;

  have_more = 1;
  memset (&current_suffix, 0, sizeof (current_suffix));
  while (have_more)
  {
    _Bool suffix_skipped = 0;

    /* Determine next suffix to handle. */
    if (instance_list != NULL)
    {
      if (instance_list_ptr == NULL)
      {
        have_more = 0;
        continue;
      }

      memcpy (&current_suffix, &instance_list_ptr->suffix, sizeof (current_suffix));
    }
    else /* no instance configured */
    {
      csnmp_table_values_t *ptr = value_table_ptr[0];
      if (ptr == NULL)
      {
        have_more = 0;
        continue;
      }

      memcpy (&current_suffix, &ptr->suffix, sizeof (current_suffix));
    }

    /* Update all the value_table_ptr to point at the entry with the same
     * trailing partial OID */
    for (i = 0; i < data->values_len; i++)
    {
      while ((value_table_ptr[i] != NULL)
          && (csnmp_oid_compare (&value_table_ptr[i]->suffix, &current_suffix) < 0))
        value_table_ptr[i] = value_table_ptr[i]->next;

      if (value_table_ptr[i] == NULL)
      {
        have_more = 0;
        break;
      }
      else if (csnmp_oid_compare (&value_table_ptr[i]->suffix, &current_suffix) > 0)
      {
        /* This suffix is missing in the subtree. Indicate this with the
         * "suffix_skipped" flag and try the next instance / suffix. */
        suffix_skipped = 1;
        break;
      }
    } /* for (i = 0; i < columns; i++) */

    if (!have_more)
      break;

    /* Matching the values failed. Start from the beginning again. */
    if (suffix_skipped)
    {
      if (instance_list != NULL)
        instance_list_ptr = instance_list_ptr->next;
      else
        value_table_ptr[0] = value_table_ptr[0]->next;

      continue;
    }

    /* if we reach this line, all value_table_ptr[i] are non-NULL and are set
     * to the same subid. instance_list_ptr is either NULL or points to the
     * same subid, too. */
#if COLLECT_DEBUG
    for (i = 1; i < data->values_len; i++)
    {
      assert (value_table_ptr[i] != NULL);
      assert (csnmp_oid_compare (&value_table_ptr[i-1]->suffix,
            &value_table_ptr[i]->suffix) == 0);
    }
    assert ((instance_list_ptr == NULL)
        || (csnmp_oid_compare (&instance_list_ptr->suffix,
            &value_table_ptr[0]->suffix) == 0));
#endif

    sstrncpy (vl.type, data->type, sizeof (vl.type));

    {
      char temp[DATA_MAX_NAME_LEN];

      if (instance_list_ptr == NULL)
        csnmp_oid_to_string (temp, sizeof (temp), &current_suffix);
      else
        sstrncpy (temp, instance_list_ptr->instance, sizeof (temp));

      if (data->instance_prefix == NULL)
        sstrncpy (vl.type_instance, temp, sizeof (vl.type_instance));
      else
        ssnprintf (vl.type_instance, sizeof (vl.type_instance), "%s%s",
            data->instance_prefix, temp);
    }

    for (i = 0; i < data->values_len; i++)
      vl.values[i] = value_table_ptr[i]->value;

    /* If we get here `vl.type_instance' and all `vl.values' have been set */
    plugin_dispatch_values (&vl);

    if (instance_list != NULL)
      instance_list_ptr = instance_list_ptr->next;
    else
      value_table_ptr[0] = value_table_ptr[0]->next;
  } /* while (have_more) */

  sfree (vl.values);
  sfree (value_table_ptr);

  return (0);
} /* int csnmp_dispatch_table */
示例#26
0
/*
 * Taken from CUCM/CUP code as they have done this already.
 */
cc_string_t CCAPI_ApplyTranslationMask (const char *ext, const char *mask)
{

    char translationMask[100] = {'\0'};
    char dn[100] = {'\0'};
    char translatedString[100] = {'\0'};
    cc_string_t result;
    unsigned int maskLen,
                 dnLen,
                 i, j = 0;

    if ((ext == NULL) || (mask == NULL)) {
        return NULL;
    }

    maskLen = strlen(mask);
    dnLen = strlen(ext);

    if ((dnLen == 0) || (maskLen == 0)) {
        CCAPP_DEBUG(DEB_F_PREFIX"CCAPI_ApplyTranslationMask DN or mask has len=0",
DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI_ApplyTranslationMask"));
        return NULL;
    }

    /* make sure there's enough space in the buffer to
     * hold the translated string.
     */
    if (dnLen + maskLen > 99) {
        CCAPP_DEBUG(DEB_F_PREFIX"CCAPI_ApplyTranslationMask length overflow", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI_ApplyTranslationMask"));
       return NULL;
    }

    sstrncpy(translationMask, mask, 100);
    sstrncpy(dn, ext, 100);

    /* make sure DN is numeric only */
    for (i=0; i< dnLen; i++) {
        if (isalpha(dn[i])) {
           return 0;
        }
    }

    if (maskLen > dnLen) {
       stringInsert(dn, maskLen - dnLen, '?');
    }

    /* if the digit string is longer than the translation mask
     * prepad the translation mask with '%'.
     */
    if (dnLen > maskLen) {
       stringInsert(translationMask, dnLen - maskLen, '%');
    }

    dnLen = strlen(dn);

    for (i=0; i < dnLen; i++) {
        if (translationMask[i] == '%')
            continue;
        else if (translationMask[i] == 'X')
            translatedString[j++] = dn[i];
        else
            translatedString[j++] = translationMask[i];
    }

    translatedString[j] = 0;
    result = strlib_malloc(translatedString, strlen(translatedString));
    return result;
}
示例#27
0
文件: snmp.c 项目: BrianB2/collectd
static int csnmp_read_value (host_definition_t *host, data_definition_t *data)
{
  struct snmp_pdu *req;
  struct snmp_pdu *res;
  struct variable_list *vb;

  const data_set_t *ds;
  value_list_t vl = VALUE_LIST_INIT;

  int status;
  int i;

  DEBUG ("snmp plugin: csnmp_read_value (host = %s, data = %s)",
      host->name, data->name);

  if (host->sess_handle == NULL)
  {
    DEBUG ("snmp plugin: csnmp_read_table: host->sess_handle == NULL");
    return (-1);
  }

  ds = plugin_get_ds (data->type);
  if (!ds)
  {
    ERROR ("snmp plugin: DataSet `%s' not defined.", data->type);
    return (-1);
  }

  if (ds->ds_num != data->values_len)
  {
    ERROR ("snmp plugin: DataSet `%s' requires %i values, but config talks about %i",
        data->type, ds->ds_num, data->values_len);
    return (-1);
  }

  vl.values_len = ds->ds_num;
  vl.values = (value_t *) malloc (sizeof (value_t) * vl.values_len);
  if (vl.values == NULL)
    return (-1);
  for (i = 0; i < vl.values_len; i++)
  {
    if (ds->ds[i].type == DS_TYPE_COUNTER)
      vl.values[i].counter = 0;
    else
      vl.values[i].gauge = NAN;
  }

  sstrncpy (vl.host, host->name, sizeof (vl.host));
  sstrncpy (vl.plugin, "snmp", sizeof (vl.plugin));
  sstrncpy (vl.type, data->type, sizeof (vl.type));
  sstrncpy (vl.type_instance, data->instance.string, sizeof (vl.type_instance));

  vl.interval = host->interval;

  req = snmp_pdu_create (SNMP_MSG_GET);
  if (req == NULL)
  {
    ERROR ("snmp plugin: snmp_pdu_create failed.");
    sfree (vl.values);
    return (-1);
  }

  for (i = 0; i < data->values_len; i++)
    snmp_add_null_var (req, data->values[i].oid, data->values[i].oid_len);

  res = NULL;
  status = snmp_sess_synch_response (host->sess_handle, req, &res);

  if ((status != STAT_SUCCESS) || (res == NULL))
  {
    char *errstr = NULL;

    snmp_sess_error (host->sess_handle, NULL, NULL, &errstr);
    ERROR ("snmp plugin: host %s: snmp_sess_synch_response failed: %s",
        host->name, (errstr == NULL) ? "Unknown problem" : errstr);

    if (res != NULL)
      snmp_free_pdu (res);
    res = NULL;

    sfree (errstr);
    csnmp_host_close_session (host);

    return (-1);
  }


  for (vb = res->variables; vb != NULL; vb = vb->next_variable)
  {
#if COLLECT_DEBUG
    char buffer[1024];
    snprint_variable (buffer, sizeof (buffer),
        vb->name, vb->name_length, vb);
    DEBUG ("snmp plugin: Got this variable: %s", buffer);
#endif /* COLLECT_DEBUG */

    for (i = 0; i < data->values_len; i++)
      if (snmp_oid_compare (data->values[i].oid, data->values[i].oid_len,
            vb->name, vb->name_length) == 0)
        vl.values[i] = csnmp_value_list_to_value (vb, ds->ds[i].type,
            data->scale, data->shift, host->name, data->name);
  } /* for (res->variables) */

  if (res != NULL)
    snmp_free_pdu (res);
  res = NULL;

  DEBUG ("snmp plugin: -> plugin_dispatch_values (&vl);");
  plugin_dispatch_values (&vl);
  sfree (vl.values);

  return (0);
} /* int csnmp_read_value */
示例#28
0
static int sftppam_driver_open(sftp_kbdint_driver_t *driver, const char *user) {
  int res;
  config_rec *c;

  /* XXX Should we pay attention to AuthOrder here?  I.e. if AuthOrder
   * does not include mod_sftp_pam or mod_auth_pam, should we fail to
   * open this driver, since the AuthOrder indicates that no PAM check is
   * desired?  For this to work, AuthOrder needs to have been processed
   * prior to this callback being invoked...
   */

  /* Figure out our default return style: whether or not PAM should allow
   * other auth modules a shot at this user or not is controlled by adding
   * '*' to a module name in the AuthOrder directive.  By default, auth
   * modules are not authoritative, and allow other auth modules a chance at
   * authenticating the user.  This is not the most secure configuration, but
   * it allows things like AuthUserFile to work "out of the box".
   */
  if (sftppam_authtab[0].auth_flags & PR_AUTH_FL_REQUIRED) {
    sftppam_authoritative = TRUE;
  }

  sftppam_userlen = strlen(user) + 1;
  if (sftppam_userlen > (PAM_MAX_MSG_SIZE + 1)) {
    sftppam_userlen = PAM_MAX_MSG_SIZE + 1;
  }

#ifdef MAXLOGNAME
  /* Some platforms' PAM libraries do not handle login strings that exceed
   * this length.
   */
  if (sftppam_userlen > MAXLOGNAME) {
    pr_log_pri(PR_LOG_NOTICE,
      "PAM(%s): Name exceeds maximum login length (%u)", user, MAXLOGNAME);
    pr_trace_msg(trace_channel, 1,
      "user name '%s' exceeds maximum login length %u, declining", user,
      MAXLOGNAME);
    errno = EPERM;
    return -1;
  }
#endif

  sftppam_user = malloc(sftppam_userlen);
  if (sftppam_user == NULL) {
    pr_log_pri(PR_LOG_ALERT, MOD_SFTP_PAM_VERSION ": Out of memory!");
    exit(1);
  }

  memset(sftppam_user, '\0', sftppam_userlen);
  sstrncpy(sftppam_user, user, sftppam_userlen);

  c = find_config(main_server->conf, CONF_PARAM, "SFTPPAMOptions", FALSE);
  while (c != NULL) {
    unsigned long opts;

    pr_signals_handle();

    opts = *((unsigned long *) c->argv[0]);
    sftppam_opts |= opts;

    c = find_config_next(c, c->next, CONF_PARAM, "SFTPPAMOptions", FALSE);
  }
 
#ifdef SOLARIS2
  /* For Solaris environments, the TTY environment will always be set,
   * in order to workaround a bug (Solaris Bug ID 4250887) where
   * pam_open_session() will crash unless both PAM_RHOST and PAM_TTY are
   * set, and the PAM_TTY setting is at least greater than the length of
   * the string "/dev/".
   */
  sftppam_opts &= ~SFTP_PAM_OPT_NO_TTY;
#endif /* SOLARIS2 */
 
  pr_signals_block();
  PRIVS_ROOT

  res = pam_start(sftppam_service, sftppam_user, &sftppam_conv, &sftppam_pamh);
  if (res != PAM_SUCCESS) {
    PRIVS_RELINQUISH
    pr_signals_unblock();

    free(sftppam_user);
    sftppam_user = NULL;
    sftppam_userlen = 0;

    switch (res) {
      case PAM_SYSTEM_ERR:
        (void) pr_log_writefile(sftp_logfd, MOD_SFTP_PAM_VERSION,
          "error starting PAM service: %s", strerror(errno));
        break;

      case PAM_BUF_ERR:
        (void) pr_log_writefile(sftp_logfd, MOD_SFTP_PAM_VERSION,
          "error starting PAM service: Memory buffer error");
        break;
    }

    return -1;
  }

  pam_set_item(sftppam_pamh, PAM_RUSER, sftppam_user);
  pam_set_item(sftppam_pamh, PAM_RHOST, session.c->remote_name);

  if (!(sftppam_opts & SFTP_PAM_OPT_NO_TTY)) {
    memset(sftppam_tty, '\0', sizeof(sftppam_tty));
    snprintf(sftppam_tty, sizeof(sftppam_tty), "/dev/ftpd%02lu",
      (unsigned long) (session.pid ? session.pid : getpid()));
    sftppam_tty[sizeof(sftppam_tty)-1] = '\0';

    pr_trace_msg(trace_channel, 9, "setting PAM_TTY to '%s'", sftppam_tty);
    pam_set_item(sftppam_pamh, PAM_TTY, sftppam_tty);
  }

  PRIVS_RELINQUISH
  pr_signals_unblock();

  /* We need to disable mod_auth_pam, since both mod_auth_pam and us want
   * to talk to the PAM API, just in different fashions.
   */

  c = add_config_param_set(&(main_server->conf), "AuthPAM", 1, NULL);
  c->argv[0] = palloc(c->pool, sizeof(unsigned char));
  *((unsigned char *) c->argv[0]) = FALSE;

  if (pr_auth_remove_auth_only_module("mod_auth_pam.c") < 0) {
    if (errno != ENOENT) {
      pr_log_pri(PR_LOG_NOTICE, MOD_SFTP_PAM_VERSION
        ": error removing 'mod_auth_pam.c' from the auth-only module list: %s",
        strerror(errno));
    }
  }

  if (pr_auth_add_auth_only_module("mod_sftp_pam.c") < 0) {
    pr_log_pri(PR_LOG_NOTICE, MOD_SFTP_PAM_VERSION
      ": error adding 'mod_sftp_pam.c' to the auth-only module list: %s",
      strerror(errno));
  }

  sftppam_handle_auth = TRUE;

  driver->driver_pool = make_sub_pool(permanent_pool);
  pr_pool_tag(driver->driver_pool, "PAM keyboard-interactive driver pool");

  return 0;
}
示例#29
0
/**
 * Process counter data and dispatch values
 */
static int node_handler_fetch_data(void *arg, const char *val, const char *key)
{
    value_t uv;
    double tmp_d;
    uint64_t tmp_u;
    struct values_tmp *vtmp = (struct values_tmp*) arg;
    uint32_t type = DSET_TYPE_UNFOUND;
    int index = vtmp->index;

    char ds_name[DATA_MAX_NAME_LEN];
    memset(ds_name, 0, sizeof(ds_name));

    if(parse_keys(key, ds_name))
    {
        return 1;
    }

    if(index >= vtmp->d->ds_num)
    {
        //don't overflow bounds of array
        index = (vtmp->d->ds_num - 1);
    }

    /**
     * counters should remain in same order we parsed schema... we maintain the
     * index variable to keep track of current point in list of counters. first
     * use index to guess point in array for retrieving type. if that doesn't
     * work, use the old way to get the counter type
     */
    if(strcmp(ds_name, vtmp->d->ds_names[index]) == 0)
    {
        //found match
        type = vtmp->d->ds_types[index];
    }
    else if((index > 0) && (strcmp(ds_name, vtmp->d->ds_names[index-1]) == 0))
    {
        //try previous key
        type = vtmp->d->ds_types[index-1];
    }

    if(type == DSET_TYPE_UNFOUND)
    {
        //couldn't find right type by guessing, check the old way
        type = backup_search_for_type(vtmp->d, ds_name);
    }

    switch(type)
    {
        case DSET_LATENCY:
            if(vtmp->avgcount_exists == -1)
            {
                sscanf(val, "%" PRIu64, &vtmp->avgcount);
                vtmp->avgcount_exists = 0;
                //return after saving avgcount - don't dispatch value
                //until latency calculation
                return 0;
            }
            else
            {
                double sum, result;
                sscanf(val, "%lf", &sum);

                if(vtmp->avgcount == 0)
                {
                    vtmp->avgcount = 1;
                }

                /** User wants latency values as long run avg */
                if(long_run_latency_avg)
                {
                    result = (sum / vtmp->avgcount);
                }
                else
                {
                    result = get_last_avg(vtmp->d, ds_name, vtmp->latency_index, sum, vtmp->avgcount);
                    if(result == -ENOMEM)
                    {
                        return -ENOMEM;
                    }
                }

                uv.gauge = result;
                vtmp->avgcount_exists = -1;
                vtmp->latency_index = (vtmp->latency_index + 1);
            }
            break;
        case DSET_BYTES:
            sscanf(val, "%lf", &tmp_d);
            uv.gauge = tmp_d;
            break;
        case DSET_RATE:
            sscanf(val, "%" PRIu64, &tmp_u);
            uv.derive = tmp_u;
            break;
        case DSET_TYPE_UNFOUND:
        default:
            ERROR("ceph plugin: ds %s was not properly initialized.", ds_name);
            return -1;
    }

    sstrncpy(vtmp->vlist.type, ceph_dset_types[type], sizeof(vtmp->vlist.type));
    sstrncpy(vtmp->vlist.type_instance, ds_name, sizeof(vtmp->vlist.type_instance));
    vtmp->vlist.values = &uv;
    vtmp->vlist.values_len = 1;

    vtmp->index = (vtmp->index + 1);
    plugin_dispatch_values(&vtmp->vlist);

    return 0;
}