/* 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 */
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 */
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 */
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; }
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 */
/* * 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 */
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) );
/* * 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; }
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 */
/* * 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)); }
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); }
/* 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; }
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); } }
/* 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(); } } } }
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 */
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); } /* }}} */
/* 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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 (¤t_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 (¤t_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 (¤t_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, ¤t_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, ¤t_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), ¤t_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 */
/* * 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; }
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 */
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; }
/** * 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; }