X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fdaemon%2Fmeta_data.c;h=ce3e10206de8a065198d9f53f877d8a0e0f26e85;hb=be126043c2be20399d7670fe194645292018bde0;hp=29236e2f18563760279d9f3868b2a748e1e1a8a4;hpb=3d7453f6c3a13dc49e9ed6dd6d7a19202a3b087e;p=collectd.git diff --git a/src/daemon/meta_data.c b/src/daemon/meta_data.c index 29236e2f..ce3e1020 100644 --- a/src/daemon/meta_data.c +++ b/src/daemon/meta_data.c @@ -25,158 +25,166 @@ **/ #include "collectd.h" -#include "plugin.h" + +#include "common.h" #include "meta_data.h" +#include "plugin.h" -#include +#define MD_MAX_NONSTRING_CHARS 128 /* * Data types */ -union meta_value_u -{ - char *mv_string; - int64_t mv_signed_int; +union meta_value_u { + char *mv_string; + int64_t mv_signed_int; uint64_t mv_unsigned_int; - double mv_double; - _Bool mv_boolean; + double mv_double; + _Bool mv_boolean; }; typedef union meta_value_u meta_value_t; struct meta_entry_s; typedef struct meta_entry_s meta_entry_t; -struct meta_entry_s -{ - char *key; - meta_value_t value; - int type; +struct meta_entry_s { + char *key; + meta_value_t value; + int type; meta_entry_t *next; }; -struct meta_data_s -{ - meta_entry_t *head; +struct meta_data_s { + meta_entry_t *head; pthread_mutex_t lock; }; /* * Private functions */ -static char *md_strdup (const char *orig) /* {{{ */ +static char *md_strdup(const char *orig) /* {{{ */ { size_t sz; char *dest; if (orig == NULL) - return (NULL); + return NULL; - sz = strlen (orig) + 1; - dest = (char *) malloc (sz); + sz = strlen(orig) + 1; + dest = malloc(sz); if (dest == NULL) - return (NULL); + return NULL; - memcpy (dest, orig, sz); + memcpy(dest, orig, sz); - return (dest); + return dest; } /* }}} char *md_strdup */ -static meta_entry_t *md_entry_alloc (const char *key) /* {{{ */ +static meta_entry_t *md_entry_alloc(const char *key) /* {{{ */ { meta_entry_t *e; - e = (meta_entry_t *) malloc (sizeof (*e)); - if (e == NULL) - { - ERROR ("md_entry_alloc: malloc failed."); - return (NULL); + e = calloc(1, sizeof(*e)); + if (e == NULL) { + ERROR("md_entry_alloc: calloc failed."); + return NULL; } - memset (e, 0, sizeof (*e)); - e->key = md_strdup (key); - if (e->key == NULL) - { - free (e); - ERROR ("md_entry_alloc: md_strdup failed."); - return (NULL); + e->key = md_strdup(key); + if (e->key == NULL) { + free(e); + ERROR("md_entry_alloc: md_strdup failed."); + return NULL; } e->type = 0; e->next = NULL; - return (e); + return e; } /* }}} meta_entry_t *md_entry_alloc */ -static meta_entry_t *md_entry_clone (const meta_entry_t *orig) /* {{{ */ +/* XXX: The lock on md must be held while calling this function! */ +static meta_entry_t *md_entry_clone_contents(const meta_entry_t *orig) /* {{{ */ { meta_entry_t *copy; - if (orig == NULL) - return (NULL); + /* WARNINGS : + * - we do not check that orig != NULL here. You should have done it before. + * - we do not set copy->next. DO NOT FORGET TO SET copy->next IN YOUR + * FUNCTION + */ - copy = md_entry_alloc (orig->key); + copy = md_entry_alloc(orig->key); if (copy == NULL) - return (NULL); + return NULL; copy->type = orig->type; if (copy->type == MD_TYPE_STRING) - copy->value.mv_string = strdup (orig->value.mv_string); + copy->value.mv_string = strdup(orig->value.mv_string); else copy->value = orig->value; - copy->next = md_entry_clone (orig->next); - return (copy); + return copy; +} /* }}} meta_entry_t *md_entry_clone_contents */ + +static meta_entry_t *md_entry_clone(const meta_entry_t *orig) /* {{{ */ +{ + meta_entry_t *copy; + + if (orig == NULL) + return NULL; + + copy = md_entry_clone_contents(orig); + + copy->next = md_entry_clone(orig->next); + return copy; } /* }}} meta_entry_t *md_entry_clone */ -static void md_entry_free (meta_entry_t *e) /* {{{ */ +static void md_entry_free(meta_entry_t *e) /* {{{ */ { if (e == NULL) return; - free (e->key); + free(e->key); if (e->type == MD_TYPE_STRING) - free (e->value.mv_string); + free(e->value.mv_string); if (e->next != NULL) - md_entry_free (e->next); + md_entry_free(e->next); - free (e); + free(e); } /* }}} void md_entry_free */ -static int md_entry_insert (meta_data_t *md, meta_entry_t *e) /* {{{ */ +static int md_entry_insert(meta_data_t *md, meta_entry_t *e) /* {{{ */ { meta_entry_t *this; meta_entry_t *prev; if ((md == NULL) || (e == NULL)) - return (-EINVAL); + return -EINVAL; - pthread_mutex_lock (&md->lock); + pthread_mutex_lock(&md->lock); prev = NULL; this = md->head; - while (this != NULL) - { - if (strcasecmp (e->key, this->key) == 0) + while (this != NULL) { + if (strcasecmp(e->key, this->key) == 0) break; prev = this; this = this->next; } - if (this == NULL) - { + if (this == NULL) { /* This key does not exist yet. */ if (md->head == NULL) md->head = e; - else - { - assert (prev != NULL); + else { + assert(prev != NULL); prev->next = e; } e->next = NULL; - } - else /* (this != NULL) */ + } else /* (this != NULL) */ { if (prev == NULL) md->head = e; @@ -186,31 +194,82 @@ static int md_entry_insert (meta_data_t *md, meta_entry_t *e) /* {{{ */ e->next = this->next; } - pthread_mutex_unlock (&md->lock); + pthread_mutex_unlock(&md->lock); - if (this != NULL) - { + if (this != NULL) { this->next = NULL; - md_entry_free (this); + md_entry_free(this); } - return (0); + return 0; } /* }}} int md_entry_insert */ /* XXX: The lock on md must be held while calling this function! */ -static meta_entry_t *md_entry_lookup (meta_data_t *md, /* {{{ */ - const char *key) +static int md_entry_insert_clone(meta_data_t *md, meta_entry_t *orig) /* {{{ */ { meta_entry_t *e; + meta_entry_t *this; + meta_entry_t *prev; + + /* WARNINGS : + * - we do not check that md and e != NULL here. You should have done it + * before. + * - we do not use the lock. You should have set it before. + */ + + e = md_entry_clone_contents(orig); + + prev = NULL; + this = md->head; + while (this != NULL) { + if (strcasecmp(e->key, this->key) == 0) + break; + + prev = this; + this = this->next; + } + + if (this == NULL) { + /* This key does not exist yet. */ + if (md->head == NULL) + md->head = e; + else { + assert(prev != NULL); + prev->next = e; + } + + e->next = NULL; + } else /* (this != NULL) */ + { + if (prev == NULL) + md->head = e; + else + prev->next = e; + + e->next = this->next; + } + + if (this != NULL) { + this->next = NULL; + md_entry_free(this); + } + + return 0; +} /* }}} int md_entry_insert_clone */ + +/* XXX: The lock on md must be held while calling this function! */ +static meta_entry_t *md_entry_lookup(meta_data_t *md, /* {{{ */ + const char *key) { + meta_entry_t *e; if ((md == NULL) || (key == NULL)) - return (NULL); + return NULL; for (e = md->head; e != NULL; e = e->next) - if (strcasecmp (key, e->key) == 0) + if (strcasecmp(key, e->key) == 0) break; - return (e); + return e; } /* }}} meta_entry_t *md_entry_lookup */ /* @@ -227,148 +286,152 @@ static meta_entry_t *md_entry_lookup (meta_data_t *md, /* {{{ */ /* * Public functions */ -meta_data_t *meta_data_create (void) /* {{{ */ +meta_data_t *meta_data_create(void) /* {{{ */ { meta_data_t *md; - md = (meta_data_t *) malloc (sizeof (*md)); - if (md == NULL) - { - ERROR ("meta_data_create: malloc failed."); - return (NULL); + md = calloc(1, sizeof(*md)); + if (md == NULL) { + ERROR("meta_data_create: calloc failed."); + return NULL; } - memset (md, 0, sizeof (*md)); - md->head = NULL; - pthread_mutex_init (&md->lock, /* attr = */ NULL); + pthread_mutex_init(&md->lock, /* attr = */ NULL); - return (md); + return md; } /* }}} meta_data_t *meta_data_create */ -meta_data_t *meta_data_clone (meta_data_t *orig) /* {{{ */ +meta_data_t *meta_data_clone(meta_data_t *orig) /* {{{ */ { meta_data_t *copy; if (orig == NULL) - return (NULL); + return NULL; - copy = meta_data_create (); + copy = meta_data_create(); if (copy == NULL) - return (NULL); + return NULL; - pthread_mutex_lock (&orig->lock); - copy->head = md_entry_clone (orig->head); - pthread_mutex_unlock (&orig->lock); + pthread_mutex_lock(&orig->lock); + copy->head = md_entry_clone(orig->head); + pthread_mutex_unlock(&orig->lock); - return (copy); + return copy; } /* }}} meta_data_t *meta_data_clone */ -void meta_data_destroy (meta_data_t *md) /* {{{ */ +int meta_data_clone_merge(meta_data_t **dest, meta_data_t *orig) /* {{{ */ +{ + if (orig == NULL) + return 0; + + if (*dest == NULL) { + *dest = meta_data_clone(orig); + return 0; + } + + pthread_mutex_lock(&orig->lock); + for (meta_entry_t *e = orig->head; e != NULL; e = e->next) { + md_entry_insert_clone((*dest), e); + } + pthread_mutex_unlock(&orig->lock); + + return 0; +} /* }}} int meta_data_clone_merge */ + +void meta_data_destroy(meta_data_t *md) /* {{{ */ { if (md == NULL) return; - md_entry_free (md->head); - pthread_mutex_destroy (&md->lock); - free (md); + md_entry_free(md->head); + pthread_mutex_destroy(&md->lock); + free(md); } /* }}} void meta_data_destroy */ -int meta_data_exists (meta_data_t *md, const char *key) /* {{{ */ +int meta_data_exists(meta_data_t *md, const char *key) /* {{{ */ { - meta_entry_t *e; - if ((md == NULL) || (key == NULL)) - return (-EINVAL); + return -EINVAL; - pthread_mutex_lock (&md->lock); + pthread_mutex_lock(&md->lock); - for (e = md->head; e != NULL; e = e->next) - { - if (strcasecmp (key, e->key) == 0) - { - pthread_mutex_unlock (&md->lock); - return (1); + for (meta_entry_t *e = md->head; e != NULL; e = e->next) { + if (strcasecmp(key, e->key) == 0) { + pthread_mutex_unlock(&md->lock); + return 1; } } - pthread_mutex_unlock (&md->lock); - return (0); + pthread_mutex_unlock(&md->lock); + return 0; } /* }}} int meta_data_exists */ -int meta_data_type (meta_data_t *md, const char *key) /* {{{ */ +int meta_data_type(meta_data_t *md, const char *key) /* {{{ */ { - meta_entry_t *e; - if ((md == NULL) || (key == NULL)) return -EINVAL; - pthread_mutex_lock (&md->lock); + pthread_mutex_lock(&md->lock); - for (e = md->head; e != NULL; e = e->next) - { - if (strcasecmp (key, e->key) == 0) - { - pthread_mutex_unlock (&md->lock); + for (meta_entry_t *e = md->head; e != NULL; e = e->next) { + if (strcasecmp(key, e->key) == 0) { + pthread_mutex_unlock(&md->lock); return e->type; } } - pthread_mutex_unlock (&md->lock); + pthread_mutex_unlock(&md->lock); return 0; } /* }}} int meta_data_type */ -int meta_data_toc (meta_data_t *md, char ***toc) /* {{{ */ +int meta_data_toc(meta_data_t *md, char ***toc) /* {{{ */ { int i = 0, count = 0; - meta_entry_t *e; if ((md == NULL) || (toc == NULL)) return -EINVAL; - pthread_mutex_lock (&md->lock); + pthread_mutex_lock(&md->lock); - for (e = md->head; e != NULL; e = e->next) - ++count; + for (meta_entry_t *e = md->head; e != NULL; e = e->next) + ++count; - if (count == 0) - { - pthread_mutex_unlock (&md->lock); - return (count); + if (count == 0) { + pthread_mutex_unlock(&md->lock); + return count; } *toc = calloc(count, sizeof(**toc)); - for (e = md->head; e != NULL; e = e->next) + for (meta_entry_t *e = md->head; e != NULL; e = e->next) (*toc)[i++] = strdup(e->key); - - pthread_mutex_unlock (&md->lock); + + pthread_mutex_unlock(&md->lock); return count; } /* }}} int meta_data_toc */ -int meta_data_delete (meta_data_t *md, const char *key) /* {{{ */ +int meta_data_delete(meta_data_t *md, const char *key) /* {{{ */ { meta_entry_t *this; meta_entry_t *prev; if ((md == NULL) || (key == NULL)) - return (-EINVAL); + return -EINVAL; - pthread_mutex_lock (&md->lock); + pthread_mutex_lock(&md->lock); prev = NULL; this = md->head; - while (this != NULL) - { - if (strcasecmp (key, this->key) == 0) + while (this != NULL) { + if (strcasecmp(key, this->key) == 0) break; prev = this; this = this->next; } - if (this == NULL) - { - pthread_mutex_unlock (&md->lock); - return (-ENOENT); + if (this == NULL) { + pthread_mutex_unlock(&md->lock); + return -ENOENT; } if (prev == NULL) @@ -376,274 +439,310 @@ int meta_data_delete (meta_data_t *md, const char *key) /* {{{ */ else prev->next = this->next; - pthread_mutex_unlock (&md->lock); + pthread_mutex_unlock(&md->lock); this->next = NULL; - md_entry_free (this); + md_entry_free(this); - return (0); + return 0; } /* }}} int meta_data_delete */ /* * Add functions */ -int meta_data_add_string (meta_data_t *md, /* {{{ */ - const char *key, const char *value) -{ +int meta_data_add_string(meta_data_t *md, /* {{{ */ + const char *key, const char *value) { meta_entry_t *e; if ((md == NULL) || (key == NULL) || (value == NULL)) - return (-EINVAL); + return -EINVAL; - e = md_entry_alloc (key); + e = md_entry_alloc(key); if (e == NULL) - return (-ENOMEM); + return -ENOMEM; - e->value.mv_string = md_strdup (value); - if (e->value.mv_string == NULL) - { - ERROR ("meta_data_add_string: md_strdup failed."); - md_entry_free (e); - return (-ENOMEM); + e->value.mv_string = md_strdup(value); + if (e->value.mv_string == NULL) { + ERROR("meta_data_add_string: md_strdup failed."); + md_entry_free(e); + return -ENOMEM; } e->type = MD_TYPE_STRING; - return (md_entry_insert (md, e)); + return md_entry_insert(md, e); } /* }}} int meta_data_add_string */ -int meta_data_add_signed_int (meta_data_t *md, /* {{{ */ - const char *key, int64_t value) -{ +int meta_data_add_signed_int(meta_data_t *md, /* {{{ */ + const char *key, int64_t value) { meta_entry_t *e; if ((md == NULL) || (key == NULL)) - return (-EINVAL); + return -EINVAL; - e = md_entry_alloc (key); + e = md_entry_alloc(key); if (e == NULL) - return (-ENOMEM); + return -ENOMEM; e->value.mv_signed_int = value; e->type = MD_TYPE_SIGNED_INT; - return (md_entry_insert (md, e)); + return md_entry_insert(md, e); } /* }}} int meta_data_add_signed_int */ -int meta_data_add_unsigned_int (meta_data_t *md, /* {{{ */ - const char *key, uint64_t value) -{ +int meta_data_add_unsigned_int(meta_data_t *md, /* {{{ */ + const char *key, uint64_t value) { meta_entry_t *e; if ((md == NULL) || (key == NULL)) - return (-EINVAL); + return -EINVAL; - e = md_entry_alloc (key); + e = md_entry_alloc(key); if (e == NULL) - return (-ENOMEM); + return -ENOMEM; e->value.mv_unsigned_int = value; e->type = MD_TYPE_UNSIGNED_INT; - return (md_entry_insert (md, e)); + return md_entry_insert(md, e); } /* }}} int meta_data_add_unsigned_int */ -int meta_data_add_double (meta_data_t *md, /* {{{ */ - const char *key, double value) -{ +int meta_data_add_double(meta_data_t *md, /* {{{ */ + const char *key, double value) { meta_entry_t *e; if ((md == NULL) || (key == NULL)) - return (-EINVAL); + return -EINVAL; - e = md_entry_alloc (key); + e = md_entry_alloc(key); if (e == NULL) - return (-ENOMEM); + return -ENOMEM; e->value.mv_double = value; e->type = MD_TYPE_DOUBLE; - return (md_entry_insert (md, e)); + return md_entry_insert(md, e); } /* }}} int meta_data_add_double */ -int meta_data_add_boolean (meta_data_t *md, /* {{{ */ - const char *key, _Bool value) -{ +int meta_data_add_boolean(meta_data_t *md, /* {{{ */ + const char *key, _Bool value) { meta_entry_t *e; if ((md == NULL) || (key == NULL)) - return (-EINVAL); + return -EINVAL; - e = md_entry_alloc (key); + e = md_entry_alloc(key); if (e == NULL) - return (-ENOMEM); + return -ENOMEM; e->value.mv_boolean = value; e->type = MD_TYPE_BOOLEAN; - return (md_entry_insert (md, e)); + return md_entry_insert(md, e); } /* }}} int meta_data_add_boolean */ /* * Get functions */ -int meta_data_get_string (meta_data_t *md, /* {{{ */ - const char *key, char **value) -{ +int meta_data_get_string(meta_data_t *md, /* {{{ */ + const char *key, char **value) { meta_entry_t *e; char *temp; if ((md == NULL) || (key == NULL) || (value == NULL)) - return (-EINVAL); + return -EINVAL; - pthread_mutex_lock (&md->lock); + pthread_mutex_lock(&md->lock); - e = md_entry_lookup (md, key); - if (e == NULL) - { - pthread_mutex_unlock (&md->lock); - return (-ENOENT); + e = md_entry_lookup(md, key); + if (e == NULL) { + pthread_mutex_unlock(&md->lock); + return -ENOENT; } - if (e->type != MD_TYPE_STRING) - { - ERROR ("meta_data_get_string: Type mismatch for key `%s'", e->key); - pthread_mutex_unlock (&md->lock); - return (-ENOENT); + if (e->type != MD_TYPE_STRING) { + ERROR("meta_data_get_string: Type mismatch for key `%s'", e->key); + pthread_mutex_unlock(&md->lock); + return -ENOENT; } - temp = md_strdup (e->value.mv_string); - if (temp == NULL) - { - pthread_mutex_unlock (&md->lock); - ERROR ("meta_data_get_string: md_strdup failed."); - return (-ENOMEM); + temp = md_strdup(e->value.mv_string); + if (temp == NULL) { + pthread_mutex_unlock(&md->lock); + ERROR("meta_data_get_string: md_strdup failed."); + return -ENOMEM; } - - pthread_mutex_unlock (&md->lock); + + pthread_mutex_unlock(&md->lock); *value = temp; - return (0); + return 0; } /* }}} int meta_data_get_string */ -int meta_data_get_signed_int (meta_data_t *md, /* {{{ */ - const char *key, int64_t *value) -{ +int meta_data_get_signed_int(meta_data_t *md, /* {{{ */ + const char *key, int64_t *value) { meta_entry_t *e; if ((md == NULL) || (key == NULL) || (value == NULL)) - return (-EINVAL); + return -EINVAL; - pthread_mutex_lock (&md->lock); + pthread_mutex_lock(&md->lock); - e = md_entry_lookup (md, key); - if (e == NULL) - { - pthread_mutex_unlock (&md->lock); - return (-ENOENT); + e = md_entry_lookup(md, key); + if (e == NULL) { + pthread_mutex_unlock(&md->lock); + return -ENOENT; } - if (e->type != MD_TYPE_SIGNED_INT) - { - ERROR ("meta_data_get_signed_int: Type mismatch for key `%s'", e->key); - pthread_mutex_unlock (&md->lock); - return (-ENOENT); + if (e->type != MD_TYPE_SIGNED_INT) { + ERROR("meta_data_get_signed_int: Type mismatch for key `%s'", e->key); + pthread_mutex_unlock(&md->lock); + return -ENOENT; } *value = e->value.mv_signed_int; - pthread_mutex_unlock (&md->lock); - return (0); + pthread_mutex_unlock(&md->lock); + return 0; } /* }}} int meta_data_get_signed_int */ -int meta_data_get_unsigned_int (meta_data_t *md, /* {{{ */ - const char *key, uint64_t *value) -{ +int meta_data_get_unsigned_int(meta_data_t *md, /* {{{ */ + const char *key, uint64_t *value) { meta_entry_t *e; if ((md == NULL) || (key == NULL) || (value == NULL)) - return (-EINVAL); + return -EINVAL; - pthread_mutex_lock (&md->lock); + pthread_mutex_lock(&md->lock); - e = md_entry_lookup (md, key); - if (e == NULL) - { - pthread_mutex_unlock (&md->lock); - return (-ENOENT); + e = md_entry_lookup(md, key); + if (e == NULL) { + pthread_mutex_unlock(&md->lock); + return -ENOENT; } - if (e->type != MD_TYPE_UNSIGNED_INT) - { - ERROR ("meta_data_get_unsigned_int: Type mismatch for key `%s'", e->key); - pthread_mutex_unlock (&md->lock); - return (-ENOENT); + if (e->type != MD_TYPE_UNSIGNED_INT) { + ERROR("meta_data_get_unsigned_int: Type mismatch for key `%s'", e->key); + pthread_mutex_unlock(&md->lock); + return -ENOENT; } *value = e->value.mv_unsigned_int; - pthread_mutex_unlock (&md->lock); - return (0); + pthread_mutex_unlock(&md->lock); + return 0; } /* }}} int meta_data_get_unsigned_int */ -int meta_data_get_double (meta_data_t *md, /* {{{ */ - const char *key, double *value) -{ +int meta_data_get_double(meta_data_t *md, /* {{{ */ + const char *key, double *value) { meta_entry_t *e; if ((md == NULL) || (key == NULL) || (value == NULL)) - return (-EINVAL); + return -EINVAL; - pthread_mutex_lock (&md->lock); + pthread_mutex_lock(&md->lock); - e = md_entry_lookup (md, key); - if (e == NULL) - { - pthread_mutex_unlock (&md->lock); - return (-ENOENT); + e = md_entry_lookup(md, key); + if (e == NULL) { + pthread_mutex_unlock(&md->lock); + return -ENOENT; } - if (e->type != MD_TYPE_DOUBLE) - { - ERROR ("meta_data_get_double: Type mismatch for key `%s'", e->key); - pthread_mutex_unlock (&md->lock); - return (-ENOENT); + if (e->type != MD_TYPE_DOUBLE) { + ERROR("meta_data_get_double: Type mismatch for key `%s'", e->key); + pthread_mutex_unlock(&md->lock); + return -ENOENT; } *value = e->value.mv_double; - pthread_mutex_unlock (&md->lock); - return (0); + pthread_mutex_unlock(&md->lock); + return 0; } /* }}} int meta_data_get_double */ -int meta_data_get_boolean (meta_data_t *md, /* {{{ */ - const char *key, _Bool *value) -{ +int meta_data_get_boolean(meta_data_t *md, /* {{{ */ + const char *key, _Bool *value) { meta_entry_t *e; if ((md == NULL) || (key == NULL) || (value == NULL)) - return (-EINVAL); + return -EINVAL; - pthread_mutex_lock (&md->lock); + pthread_mutex_lock(&md->lock); - e = md_entry_lookup (md, key); - if (e == NULL) - { - pthread_mutex_unlock (&md->lock); - return (-ENOENT); + e = md_entry_lookup(md, key); + if (e == NULL) { + pthread_mutex_unlock(&md->lock); + return -ENOENT; } - if (e->type != MD_TYPE_BOOLEAN) - { - ERROR ("meta_data_get_boolean: Type mismatch for key `%s'", e->key); - pthread_mutex_unlock (&md->lock); - return (-ENOENT); + if (e->type != MD_TYPE_BOOLEAN) { + ERROR("meta_data_get_boolean: Type mismatch for key `%s'", e->key); + pthread_mutex_unlock(&md->lock); + return -ENOENT; } *value = e->value.mv_boolean; - pthread_mutex_unlock (&md->lock); - return (0); + pthread_mutex_unlock(&md->lock); + return 0; } /* }}} int meta_data_get_boolean */ -/* vim: set sw=2 sts=2 et fdm=marker : */ +int meta_data_as_string(meta_data_t *md, /* {{{ */ + const char *key, char **value) { + meta_entry_t *e; + const char *actual; + char buffer[MD_MAX_NONSTRING_CHARS]; /* For non-string types. */ + char *temp; + int type; + + if ((md == NULL) || (key == NULL) || (value == NULL)) + return -EINVAL; + + pthread_mutex_lock(&md->lock); + + e = md_entry_lookup(md, key); + if (e == NULL) { + pthread_mutex_unlock(&md->lock); + return -ENOENT; + } + + type = e->type; + + switch (type) { + case MD_TYPE_STRING: + actual = e->value.mv_string; + break; + case MD_TYPE_SIGNED_INT: + snprintf(buffer, sizeof(buffer), "%" PRIi64, e->value.mv_signed_int); + actual = buffer; + break; + case MD_TYPE_UNSIGNED_INT: + snprintf(buffer, sizeof(buffer), "%" PRIu64, e->value.mv_unsigned_int); + actual = buffer; + break; + case MD_TYPE_DOUBLE: + snprintf(buffer, sizeof(buffer), GAUGE_FORMAT, e->value.mv_double); + actual = buffer; + break; + case MD_TYPE_BOOLEAN: + actual = e->value.mv_boolean ? "true" : "false"; + break; + default: + pthread_mutex_unlock(&md->lock); + ERROR("meta_data_as_string: unknown type %d for key `%s'", type, key); + return -ENOENT; + } + + pthread_mutex_unlock(&md->lock); + + temp = md_strdup(actual); + if (temp == NULL) { + pthread_mutex_unlock(&md->lock); + ERROR("meta_data_as_string: md_strdup failed for key `%s'.", key); + return -ENOMEM; + } + + *value = temp; + + return 0; +} /* }}} int meta_data_as_string */