int lcc_putval (lcc_connection_t *c, const lcc_value_list_t *vl) /* {{{ */ { char ident_str[6 * LCC_NAME_LEN]; char ident_esc[12 * LCC_NAME_LEN]; char command[1024] = ""; lcc_response_t res; int status; size_t i; if ((c == NULL) || (vl == NULL) || (vl->values_len < 1) || (vl->values == NULL) || (vl->values_types == NULL)) { lcc_set_errno (c, EINVAL); return (-1); } status = lcc_identifier_to_string (c, ident_str, sizeof (ident_str), &vl->identifier); if (status != 0) return (status); SSTRCATF (command, "PUTVAL %s", lcc_strescape (ident_esc, ident_str, sizeof (ident_esc))); if (vl->interval > 0.0) SSTRCATF (command, " interval=%.3f", vl->interval); if (vl->time > 0.0) SSTRCATF (command, " %.3f", vl->time); else SSTRCAT (command, " N"); for (i = 0; i < vl->values_len; i++) { if (vl->values_types[i] == LCC_TYPE_COUNTER) SSTRCATF (command, ":%"PRIu64, vl->values[i].counter); else if (vl->values_types[i] == LCC_TYPE_GAUGE) { if (isnan (vl->values[i].gauge)) SSTRCATF (command, ":U"); else SSTRCATF (command, ":%g", vl->values[i].gauge); } else if (vl->values_types[i] == LCC_TYPE_DERIVE) SSTRCATF (command, ":%"PRIu64, vl->values[i].derive); else if (vl->values_types[i] == LCC_TYPE_ABSOLUTE) SSTRCATF (command, ":%"PRIu64, vl->values[i].absolute); } /* for (i = 0; i < vl->values_len; i++) */ status = lcc_sendreceive (c, command, &res); if (status != 0) return (status); if (res.status != 0) { LCC_SET_ERRSTR (c, "Server error: %s", res.message); lcc_response_free (&res); return (-1); } lcc_response_free (&res); return (0); } /* }}} int lcc_putval */
static int do_listval (lcc_connection_t *connection) { lcc_identifier_t *ret_ident = NULL; size_t ret_ident_num = 0; char *hostname = NULL; int status; size_t i; status = lcc_listval (connection, &ret_ident, &ret_ident_num); if (status != 0) { printf ("UNKNOWN: %s\n", lcc_strerror (connection)); if (ret_ident != NULL) free (ret_ident); return (RET_UNKNOWN); } status = lcc_sort_identifiers (connection, ret_ident, ret_ident_num); if (status != 0) { printf ("UNKNOWN: %s\n", lcc_strerror (connection)); if (ret_ident != NULL) free (ret_ident); return (RET_UNKNOWN); } for (i = 0; i < ret_ident_num; ++i) { char id[1024]; if ((hostname_g != NULL) && (strcasecmp (hostname_g, ret_ident[i].host))) continue; if ((hostname == NULL) || strcasecmp (hostname, ret_ident[i].host)) { free (hostname); hostname = strdup (ret_ident[i].host); printf ("Host: %s\n", hostname); } /* empty hostname; not to be printed again */ ret_ident[i].host[0] = '\0'; status = lcc_identifier_to_string (connection, id, sizeof (id), ret_ident + i); if (status != 0) { printf ("ERROR: listval: Failed to convert returned " "identifier to a string: %s\n", lcc_strerror (connection)); free (hostname); hostname = NULL; continue; } /* skip over the (empty) hostname and following '/' */ printf ("\t%s\n", id + 1); } free (ret_ident); free (hostname); return (RET_OKAY); } /* int do_listval */
int lcc_getval (lcc_connection_t *c, lcc_identifier_t *ident, /* {{{ */ size_t *ret_values_num, gauge_t **ret_values, char ***ret_values_names) { char ident_str[6 * LCC_NAME_LEN]; char ident_esc[12 * LCC_NAME_LEN]; char command[14 * LCC_NAME_LEN]; lcc_response_t res; size_t values_num; gauge_t *values = NULL; char **values_names = NULL; size_t i; int status; if (c == NULL) return (-1); if (ident == NULL) { lcc_set_errno (c, EINVAL); return (-1); } /* Build a commend with an escaped version of the identifier string. */ status = lcc_identifier_to_string (c, ident_str, sizeof (ident_str), ident); if (status != 0) return (status); snprintf (command, sizeof (command), "GETVAL %s", lcc_strescape (ident_esc, ident_str, sizeof (ident_esc))); command[sizeof (command) - 1] = 0; /* Send talk to the daemon.. */ status = lcc_sendreceive (c, command, &res); if (status != 0) return (status); if (res.status != 0) { LCC_SET_ERRSTR (c, "Server error: %s", res.message); lcc_response_free (&res); return (-1); } values_num = res.lines_num; #define BAIL_OUT(e) do { \ lcc_set_errno (c, (e)); \ free (values); \ if (values_names != NULL) { \ for (i = 0; i < values_num; i++) { \ free (values_names[i]); \ } \ } \ free (values_names); \ lcc_response_free (&res); \ return (-1); \ } while (0) /* If neither the values nor the names are requested, return here.. */ if ((ret_values == NULL) && (ret_values_names == NULL)) { if (ret_values_num != NULL) *ret_values_num = values_num; lcc_response_free (&res); return (0); } /* Allocate space for the values */ if (ret_values != NULL) { values = (gauge_t *) malloc (values_num * sizeof (*values)); if (values == NULL) BAIL_OUT (ENOMEM); } if (ret_values_names != NULL) { values_names = (char **) calloc (values_num, sizeof (*values_names)); if (values_names == NULL) BAIL_OUT (ENOMEM); } for (i = 0; i < res.lines_num; i++) { char *key; char *value; char *endptr; key = res.lines[i]; value = strchr (key, '='); if (value == NULL) BAIL_OUT (EILSEQ); *value = 0; value++; if (values != NULL) { endptr = NULL; errno = 0; values[i] = strtod (value, &endptr); if ((endptr == value) || (errno != 0)) BAIL_OUT (errno); } if (values_names != NULL) { values_names[i] = strdup (key); if (values_names[i] == NULL) BAIL_OUT (ENOMEM); } } /* for (i = 0; i < res.lines_num; i++) */ if (ret_values_num != NULL) *ret_values_num = values_num; if (ret_values != NULL) *ret_values = values; if (ret_values_names != NULL) *ret_values_names = values_names; lcc_response_free (&res); return (0); } /* }}} int lcc_getval */
static int flush(lcc_connection_t *c, int argc, char **argv) { int timeout = -1; lcc_identifier_t *identifiers = NULL; size_t identifiers_num = 0; char **plugins = NULL; size_t plugins_num = 0; int status; assert(strcasecmp(argv[0], "flush") == 0); #define BAIL_OUT(s) \ do { \ if (identifiers != NULL) \ free(identifiers); \ identifiers_num = 0; \ if (plugins != NULL) \ free(plugins); \ plugins_num = 0; \ return (s); \ } while (0) for (int i = 1; i < argc; ++i) { char *key, *value; key = argv[i]; value = strchr(argv[i], (int)'='); if (!value) { fprintf(stderr, "ERROR: flush: Invalid option ``%s''.\n", argv[i]); BAIL_OUT(-1); } *value = '\0'; ++value; if (strcasecmp(key, "timeout") == 0) { char *endptr = NULL; timeout = (int)strtol(value, &endptr, 0); if (endptr == value) { fprintf(stderr, "ERROR: Failed to parse timeout as number: %s.\n", value); BAIL_OUT(-1); } else if ((endptr != NULL) && (*endptr != '\0')) { fprintf(stderr, "WARNING: Ignoring trailing garbage after timeout: " "%s.\n", endptr); } } else if (strcasecmp(key, "plugin") == 0) { status = array_grow((void *)&plugins, &plugins_num, sizeof(*plugins)); if (status != 0) BAIL_OUT(status); plugins[plugins_num - 1] = value; } else if (strcasecmp(key, "identifier") == 0) { status = array_grow((void *)&identifiers, &identifiers_num, sizeof(*identifiers)); if (status != 0) BAIL_OUT(status); memset(identifiers + (identifiers_num - 1), 0, sizeof(*identifiers)); status = parse_identifier(c, value, identifiers + (identifiers_num - 1)); if (status != 0) BAIL_OUT(status); } else { fprintf(stderr, "ERROR: flush: Unknown option `%s'.\n", key); BAIL_OUT(-1); } } if (plugins_num == 0) { status = array_grow((void *)&plugins, &plugins_num, sizeof(*plugins)); if (status != 0) BAIL_OUT(status); assert(plugins_num == 1); plugins[0] = NULL; } for (size_t i = 0; i < plugins_num; ++i) { if (identifiers_num == 0) { status = lcc_flush(c, plugins[i], NULL, timeout); if (status != 0) fprintf(stderr, "ERROR: Failed to flush plugin `%s': %s.\n", (plugins[i] == NULL) ? "(all)" : plugins[i], lcc_strerror(c)); } else { for (size_t j = 0; j < identifiers_num; ++j) { status = lcc_flush(c, plugins[i], identifiers + j, timeout); if (status != 0) { char id[1024]; lcc_identifier_to_string(c, id, sizeof(id), identifiers + j); fprintf(stderr, "ERROR: Failed to flush plugin `%s', " "identifier `%s': %s.\n", (plugins[i] == NULL) ? "(all)" : plugins[i], id, lcc_strerror(c)); } } } } BAIL_OUT(0); #undef BAIL_OUT } /* flush */