From 23ac8e592cd64c424fddce842baea300ff8a3a85 Mon Sep 17 00:00:00 2001 From: Ruben Kerkhof Date: Thu, 4 Aug 2016 13:47:51 +0200 Subject: [PATCH] write_sensu: Re-add substitute for asprintf asprint is only available from Solaris 10 update 11. Fixes #1798 --- configure.ac | 2 +- src/write_sensu.c | 117 ++++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 84 insertions(+), 35 deletions(-) diff --git a/configure.ac b/configure.ac index eaf98ec9..5171dec8 100644 --- a/configure.ac +++ b/configure.ac @@ -786,7 +786,7 @@ AC_HEADER_TIME # # Checks for library functions. # -AC_CHECK_FUNCS(gettimeofday select strdup strtol getaddrinfo getnameinfo strchr memcpy strstr strcmp strncmp strncpy strlen strncasecmp strcasecmp openlog closelog sysconf setenv if_indextoname setlocale) +AC_CHECK_FUNCS(gettimeofday select strdup strtol getaddrinfo getnameinfo strchr memcpy strstr strcmp strncmp strncpy strlen strncasecmp strcasecmp openlog closelog sysconf setenv if_indextoname setlocale asprintf) AC_FUNC_STRERROR_R diff --git a/src/write_sensu.c b/src/write_sensu.c index 63e9aabb..b07b3bf2 100644 --- a/src/write_sensu.c +++ b/src/write_sensu.c @@ -42,6 +42,55 @@ #define SENSU_HOST "localhost" #define SENSU_PORT "3030" +#ifdef HAVE_ASPRINTF +#define my_asprintf asprintf +#define my_vasprintf vasprintf +#else +/* + * asprintf() is available from Solaris 10 update 11. + * For older versions, use asprintf() portable implementation from + * https://github.com/littlstar/asprintf.c/blob/master/ + * copyright (c) 2014 joseph werle under MIT license. + */ + +static int my_vasprintf(char **str, const char *fmt, va_list args) { + int size = 0; + va_list tmpa; + // copy + va_copy(tmpa, args); + // apply variadic arguments to + // sprintf with format to get size + size = vsnprintf(NULL, size, fmt, tmpa); + // toss args + va_end(tmpa); + // return -1 to be compliant if + // size is less than 0 + if (size < 0) { return -1; } + // alloc with size plus 1 for `\0' + *str = (char *) malloc(size + 1); + // return -1 to be compliant + // if pointer is `NULL' + if (NULL == *str) { return -1; } + // format string with original + // variadic arguments and set new size + size = vsprintf(*str, fmt, args); + return size; +} + +static int my_asprintf(char **str, const char *fmt, ...) { + int size = 0; + va_list args; + // init variadic argumens + va_start(args, fmt); + // format and get size + size = my_vasprintf(str, fmt, args); + // toss args + va_end(args); + return size; +} + +#endif + struct str_list { int nb_strs; char **strs; @@ -186,14 +235,14 @@ static char *build_json_str_list(const char *tag, struct str_list const *list) / ret_str[0] = '\0'; } - res = asprintf(&temp_str, "\"%s\": [\"%s\"", tag, list->strs[0]); + res = my_asprintf(&temp_str, "\"%s\": [\"%s\"", tag, list->strs[0]); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); free(ret_str); return NULL; } for (int i=1; inb_strs; i++) { - res = asprintf(&ret_str, "%s, \"%s\"", temp_str, list->strs[i]); + res = my_asprintf(&ret_str, "%s, \"%s\"", temp_str, list->strs[i]); free(temp_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); @@ -201,7 +250,7 @@ static char *build_json_str_list(const char *tag, struct str_list const *list) / } temp_str = ret_str; } - res = asprintf(&ret_str, "%s]", temp_str); + res = my_asprintf(&ret_str, "%s]", temp_str); free(temp_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); @@ -303,7 +352,7 @@ static char *sensu_value_to_json(struct sensu_host const *host, /* {{{ */ } } else { - res = asprintf(&ret_str, "%s, %s", part1, handlers_str); + res = my_asprintf(&ret_str, "%s, %s", part1, handlers_str); free(handlers_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); @@ -312,7 +361,7 @@ static char *sensu_value_to_json(struct sensu_host const *host, /* {{{ */ } // incorporate the plugin name information - res = asprintf(&temp_str, "%s, \"collectd_plugin\": \"%s\"", ret_str, vl->plugin); + res = my_asprintf(&temp_str, "%s, \"collectd_plugin\": \"%s\"", ret_str, vl->plugin); free(ret_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); @@ -321,7 +370,7 @@ static char *sensu_value_to_json(struct sensu_host const *host, /* {{{ */ ret_str = temp_str; // incorporate the plugin type - res = asprintf(&temp_str, "%s, \"collectd_plugin_type\": \"%s\"", ret_str, vl->type); + res = my_asprintf(&temp_str, "%s, \"collectd_plugin_type\": \"%s\"", ret_str, vl->type); free(ret_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); @@ -331,7 +380,7 @@ static char *sensu_value_to_json(struct sensu_host const *host, /* {{{ */ // incorporate the plugin instance if any if (vl->plugin_instance[0] != 0) { - res = asprintf(&temp_str, "%s, \"collectd_plugin_instance\": \"%s\"", ret_str, vl->plugin_instance); + res = my_asprintf(&temp_str, "%s, \"collectd_plugin_instance\": \"%s\"", ret_str, vl->plugin_instance); free(ret_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); @@ -342,7 +391,7 @@ static char *sensu_value_to_json(struct sensu_host const *host, /* {{{ */ // incorporate the plugin type instance if any if (vl->type_instance[0] != 0) { - res = asprintf(&temp_str, "%s, \"collectd_plugin_type_instance\": \"%s\"", ret_str, vl->type_instance); + res = my_asprintf(&temp_str, "%s, \"collectd_plugin_type_instance\": \"%s\"", ret_str, vl->type_instance); free(ret_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); @@ -355,7 +404,7 @@ static char *sensu_value_to_json(struct sensu_host const *host, /* {{{ */ 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)); - res = asprintf(&temp_str, "%s, \"collectd_data_source_type\": \"%s\"", ret_str, ds_type); + res = my_asprintf(&temp_str, "%s, \"collectd_data_source_type\": \"%s\"", ret_str, ds_type); free(ret_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); @@ -363,7 +412,7 @@ static char *sensu_value_to_json(struct sensu_host const *host, /* {{{ */ } ret_str = temp_str; } else { - res = asprintf(&temp_str, "%s, \"collectd_data_source_type\": \"%s\"", ret_str, DS_TYPE_TO_STRING(ds->ds[index].type)); + res = my_asprintf(&temp_str, "%s, \"collectd_data_source_type\": \"%s\"", ret_str, DS_TYPE_TO_STRING(ds->ds[index].type)); free(ret_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); @@ -373,7 +422,7 @@ static char *sensu_value_to_json(struct sensu_host const *host, /* {{{ */ } // incorporate the data source name - res = asprintf(&temp_str, "%s, \"collectd_data_source_name\": \"%s\"", ret_str, ds->ds[index].name); + res = my_asprintf(&temp_str, "%s, \"collectd_data_source_name\": \"%s\"", ret_str, ds->ds[index].name); free(ret_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); @@ -385,7 +434,7 @@ static char *sensu_value_to_json(struct sensu_host const *host, /* {{{ */ { char ds_index[DATA_MAX_NAME_LEN]; ssnprintf (ds_index, sizeof (ds_index), "%zu", index); - res = asprintf(&temp_str, "%s, \"collectd_data_source_index\": %s", ret_str, ds_index); + res = my_asprintf(&temp_str, "%s, \"collectd_data_source_index\": %s", ret_str, ds_index); free(ret_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); @@ -396,7 +445,7 @@ static char *sensu_value_to_json(struct sensu_host const *host, /* {{{ */ // add key value attributes from config if any for (size_t i = 0; i < sensu_attrs_num; i += 2) { - res = asprintf(&temp_str, "%s, \"%s\": \"%s\"", ret_str, sensu_attrs[i], sensu_attrs[i+1]); + res = my_asprintf(&temp_str, "%s, \"%s\": \"%s\"", ret_str, sensu_attrs[i], sensu_attrs[i+1]); free(ret_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); @@ -407,7 +456,7 @@ static char *sensu_value_to_json(struct sensu_host const *host, /* {{{ */ // incorporate sensu tags from config if any if ((sensu_tags != NULL) && (strlen(sensu_tags) != 0)) { - res = asprintf(&temp_str, "%s, %s", ret_str, sensu_tags); + res = my_asprintf(&temp_str, "%s, %s", ret_str, sensu_tags); free(ret_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); @@ -418,14 +467,14 @@ static char *sensu_value_to_json(struct sensu_host const *host, /* {{{ */ // calculate the value and set to a string if (ds->ds[index].type == DS_TYPE_GAUGE) { - res = asprintf(&value_str, GAUGE_FORMAT, vl->values[index].gauge); + res = my_asprintf(&value_str, GAUGE_FORMAT, vl->values[index].gauge); if (res == -1) { free(ret_str); ERROR("write_sensu plugin: Unable to alloc memory"); return NULL; } } else if (rates != NULL) { - res = asprintf(&value_str, GAUGE_FORMAT, rates[index]); + res = my_asprintf(&value_str, GAUGE_FORMAT, rates[index]); if (res == -1) { free(ret_str); ERROR("write_sensu plugin: Unable to alloc memory"); @@ -433,7 +482,7 @@ static char *sensu_value_to_json(struct sensu_host const *host, /* {{{ */ } } else { if (ds->ds[index].type == DS_TYPE_DERIVE) { - res = asprintf(&value_str, "%"PRIi64, vl->values[index].derive); + res = my_asprintf(&value_str, "%"PRIi64, vl->values[index].derive); if (res == -1) { free(ret_str); ERROR("write_sensu plugin: Unable to alloc memory"); @@ -441,7 +490,7 @@ static char *sensu_value_to_json(struct sensu_host const *host, /* {{{ */ } } else if (ds->ds[index].type == DS_TYPE_ABSOLUTE) { - res = asprintf(&value_str, "%"PRIu64, vl->values[index].absolute); + res = my_asprintf(&value_str, "%"PRIu64, vl->values[index].absolute); if (res == -1) { free(ret_str); ERROR("write_sensu plugin: Unable to alloc memory"); @@ -449,7 +498,7 @@ static char *sensu_value_to_json(struct sensu_host const *host, /* {{{ */ } } else { - res = asprintf(&value_str, "%llu", vl->values[index].counter); + res = my_asprintf(&value_str, "%llu", vl->values[index].counter); if (res == -1) { free(ret_str); ERROR("write_sensu plugin: Unable to alloc memory"); @@ -481,7 +530,7 @@ static char *sensu_value_to_json(struct sensu_host const *host, /* {{{ */ in_place_replace_sensu_name_reserved(service_buffer); // finalize the buffer by setting the output and closing curly bracket - res = asprintf(&temp_str, "%s, \"output\": \"%s %s %ld\"}\n", ret_str, service_buffer, value_str, CDTIME_T_TO_TIME_T(vl->time)); + res = my_asprintf(&temp_str, "%s, \"output\": \"%s %s %ld\"}\n", ret_str, service_buffer, value_str, CDTIME_T_TO_TIME_T(vl->time)); free(ret_str); free(value_str); if (res == -1) { @@ -609,7 +658,7 @@ static char *sensu_notification_to_json(struct sensu_host *host, /* {{{ */ severity = "UNKNOWN"; status = 3; } - res = asprintf(&temp_str, "{\"status\": %d", status); + res = my_asprintf(&temp_str, "{\"status\": %d", status); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); return NULL; @@ -617,7 +666,7 @@ static char *sensu_notification_to_json(struct sensu_host *host, /* {{{ */ ret_str = temp_str; // incorporate the timestamp - res = asprintf(&temp_str, "%s, \"timestamp\": %ld", ret_str, CDTIME_T_TO_TIME_T(n->time)); + res = my_asprintf(&temp_str, "%s, \"timestamp\": %ld", ret_str, CDTIME_T_TO_TIME_T(n->time)); free(ret_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); @@ -633,7 +682,7 @@ static char *sensu_notification_to_json(struct sensu_host *host, /* {{{ */ } // incorporate the handlers if (strlen(handlers_str) != 0) { - res = asprintf(&temp_str, "%s, %s", ret_str, handlers_str); + res = my_asprintf(&temp_str, "%s, %s", ret_str, handlers_str); free(ret_str); free(handlers_str); if (res == -1) { @@ -647,7 +696,7 @@ static char *sensu_notification_to_json(struct sensu_host *host, /* {{{ */ // incorporate the plugin name information if any if (n->plugin[0] != 0) { - res = asprintf(&temp_str, "%s, \"collectd_plugin\": \"%s\"", ret_str, n->plugin); + res = my_asprintf(&temp_str, "%s, \"collectd_plugin\": \"%s\"", ret_str, n->plugin); free(ret_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); @@ -658,7 +707,7 @@ static char *sensu_notification_to_json(struct sensu_host *host, /* {{{ */ // incorporate the plugin type if any if (n->type[0] != 0) { - res = asprintf(&temp_str, "%s, \"collectd_plugin_type\": \"%s\"", ret_str, n->type); + res = my_asprintf(&temp_str, "%s, \"collectd_plugin_type\": \"%s\"", ret_str, n->type); free(ret_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); @@ -669,7 +718,7 @@ static char *sensu_notification_to_json(struct sensu_host *host, /* {{{ */ // incorporate the plugin instance if any if (n->plugin_instance[0] != 0) { - res = asprintf(&temp_str, "%s, \"collectd_plugin_instance\": \"%s\"", ret_str, n->plugin_instance); + res = my_asprintf(&temp_str, "%s, \"collectd_plugin_instance\": \"%s\"", ret_str, n->plugin_instance); free(ret_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); @@ -680,7 +729,7 @@ static char *sensu_notification_to_json(struct sensu_host *host, /* {{{ */ // incorporate the plugin type instance if any if (n->type_instance[0] != 0) { - res = asprintf(&temp_str, "%s, \"collectd_plugin_type_instance\": \"%s\"", ret_str, n->type_instance); + res = my_asprintf(&temp_str, "%s, \"collectd_plugin_type_instance\": \"%s\"", ret_str, n->type_instance); free(ret_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); @@ -691,7 +740,7 @@ static char *sensu_notification_to_json(struct sensu_host *host, /* {{{ */ // add key value attributes from config if any for (i = 0; i < sensu_attrs_num; i += 2) { - res = asprintf(&temp_str, "%s, \"%s\": \"%s\"", ret_str, sensu_attrs[i], sensu_attrs[i+1]); + res = my_asprintf(&temp_str, "%s, \"%s\": \"%s\"", ret_str, sensu_attrs[i], sensu_attrs[i+1]); free(ret_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); @@ -702,7 +751,7 @@ static char *sensu_notification_to_json(struct sensu_host *host, /* {{{ */ // incorporate sensu tags from config if any if ((sensu_tags != NULL) && (strlen(sensu_tags) != 0)) { - res = asprintf(&temp_str, "%s, %s", ret_str, sensu_tags); + res = my_asprintf(&temp_str, "%s, %s", ret_str, sensu_tags); free(ret_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); @@ -717,7 +766,7 @@ static char *sensu_notification_to_json(struct sensu_host *host, /* {{{ */ n->type, n->type_instance, host->separator); // replace sensu event name chars that are considered illegal in_place_replace_sensu_name_reserved(service_buffer); - res = asprintf(&temp_str, "%s, \"name\": \"%s\"", ret_str, &service_buffer[1]); + res = my_asprintf(&temp_str, "%s, \"name\": \"%s\"", ret_str, &service_buffer[1]); free(ret_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); @@ -733,7 +782,7 @@ static char *sensu_notification_to_json(struct sensu_host *host, /* {{{ */ free(ret_str); return NULL; } - res = asprintf(&temp_str, "%s, \"output\": \"%s - %s\"", ret_str, severity, msg); + res = my_asprintf(&temp_str, "%s, \"output\": \"%s - %s\"", ret_str, severity, msg); free(ret_str); free(msg); if (res == -1) { @@ -746,7 +795,7 @@ static char *sensu_notification_to_json(struct sensu_host *host, /* {{{ */ // Pull in values from threshold and add extra attributes for (notification_meta_t *meta = n->meta; meta != NULL; meta = meta->next) { if (strcasecmp("CurrentValue", meta->name) == 0 && meta->type == NM_TYPE_DOUBLE) { - res = asprintf(&temp_str, "%s, \"current_value\": \"%.8f\"", ret_str, meta->nm_value.nm_double); + res = my_asprintf(&temp_str, "%s, \"current_value\": \"%.8f\"", ret_str, meta->nm_value.nm_double); free(ret_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); @@ -755,7 +804,7 @@ static char *sensu_notification_to_json(struct sensu_host *host, /* {{{ */ ret_str = temp_str; } if (meta->type == NM_TYPE_STRING) { - res = asprintf(&temp_str, "%s, \"%s\": \"%s\"", ret_str, meta->name, meta->nm_value.nm_string); + res = my_asprintf(&temp_str, "%s, \"%s\": \"%s\"", ret_str, meta->name, meta->nm_value.nm_string); free(ret_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); @@ -766,7 +815,7 @@ static char *sensu_notification_to_json(struct sensu_host *host, /* {{{ */ } // close the curly bracket - res = asprintf(&temp_str, "%s}\n", ret_str); + res = my_asprintf(&temp_str, "%s}\n", ret_str); free(ret_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); -- 2.11.0