diff --git a/src/core/plugin.c b/src/core/plugin.c
index c248d37eff6c15f9abce00d3d0b53b0b636a580e..fa00c0510b944dea05af3752c01769828b11cf28 100644 (file)
--- a/src/core/plugin.c
+++ b/src/core/plugin.c
int version;
int plugin_version;
};
-#define SDB_PLUGIN_INFO_INIT { "no name set", "no description set", \
- /* copyright */ "", /* license */ "", \
+#define SDB_PLUGIN_INFO_INIT { /* name */ NULL, /* desc */ NULL, \
+ /* copyright */ NULL, /* license */ NULL, \
/* version */ -1, /* plugin_version */ -1 }
+#define INFO_GET(i, attr) \
+ ((i)->attr ? (i)->attr : #attr" not set")
typedef struct {
sdb_object_t super;
#define SDB_PLUGIN_CB(obj) ((sdb_plugin_cb_t *)(obj))
#define SDB_PLUGIN_CCB(obj) ((sdb_plugin_collector_cb_t *)(obj))
+typedef struct {
+ sdb_object_t super;
+ sdb_plugin_ctx_t public;
+} ctx_t;
+#define CTX_INIT { SDB_OBJECT_INIT, \
+ SDB_PLUGIN_CTX_INIT }
+
+#define CTX(obj) ((ctx_t *)(obj))
+
/*
* private variables
*/
static sdb_plugin_ctx_t plugin_default_ctx = SDB_PLUGIN_CTX_INIT;
-static pthread_key_t plugin_ctx_key;
-static _Bool plugin_ctx_key_initialized = 0;
+static pthread_key_t plugin_ctx_key;
+static _Bool plugin_ctx_key_initialized = 0;
static sdb_llist_t *config_list = NULL;
static sdb_llist_t *init_list = NULL;
static sdb_llist_t *collector_list = NULL;
+static sdb_llist_t *cname_list = NULL;
static sdb_llist_t *shutdown_list = NULL;
static sdb_llist_t *log_list = NULL;
*/
static void
-sdb_plugin_ctx_destructor(void *ctx)
+sdb_plugin_info_clear(sdb_plugin_info_t *info)
{
- if (! ctx)
+ sdb_plugin_info_t empty_info = SDB_PLUGIN_INFO_INIT;
+ if (! info)
return;
- free(ctx);
-} /* sdb_plugin_ctx_destructor */
+
+ if (info->name)
+ free(info->name);
+ if (info->description)
+ free(info->description);
+ if (info->copyright)
+ free(info->copyright);
+ if (info->license)
+ free(info->license);
+
+ *info = empty_info;
+} /* sdb_plugin_info_clear */
+
+static void
+ctx_destructor(void *c)
+{
+ sdb_object_deref(SDB_OBJ(c));
+} /* ctx_destructor */
static void
-sdb_plugin_ctx_init(void)
+ctx_key_init(void)
{
if (plugin_ctx_key_initialized)
return;
- pthread_key_create(&plugin_ctx_key, sdb_plugin_ctx_destructor);
+ pthread_key_create(&plugin_ctx_key, ctx_destructor);
plugin_ctx_key_initialized = 1;
-} /* sdb_plugin_ctx_init */
-
-static sdb_plugin_ctx_t *
-sdb_plugin_ctx_create(void)
-{
- sdb_plugin_ctx_t *ctx;
-
- ctx = malloc(sizeof(*ctx));
- if (! ctx)
- return NULL;
-
- *ctx = plugin_default_ctx;
-
- if (! plugin_ctx_key_initialized)
- sdb_plugin_ctx_init();
- pthread_setspecific(plugin_ctx_key, ctx);
- return ctx;
-} /* sdb_plugin_ctx_create */
+} /* ctx_key_init */
static int
sdb_plugin_cmp_next_update(const sdb_object_t *a, const sdb_object_t *b)
* private types
*/
+static int
+ctx_init(sdb_object_t *obj, va_list __attribute__((unused)) ap)
+{
+ ctx_t *ctx = CTX(obj);
+
+ assert(ctx);
+
+ ctx->public = plugin_default_ctx;
+ return 0;
+} /* ctx_init */
+
+static sdb_type_t ctx_type = {
+ sizeof(ctx_t),
+
+ ctx_init,
+ NULL
+};
+
+static ctx_t *
+ctx_create(void)
+{
+ ctx_t *ctx;
+
+ ctx = CTX(sdb_object_create("plugin-context", ctx_type));
+ if (! ctx)
+ return NULL;
+
+ if (! plugin_ctx_key_initialized)
+ ctx_key_init();
+ pthread_setspecific(plugin_ctx_key, ctx);
+ return ctx;
+} /* ctx_create */
+
static int
sdb_plugin_cb_init(sdb_object_t *obj, va_list ap)
{
sizeof(sdb_plugin_cb_t),
sdb_plugin_cb_init,
- sdb_plugin_cb_destroy,
- /* clone = */ NULL
+ sdb_plugin_cb_destroy
};
static sdb_type_t sdb_plugin_collector_cb_type = {
sizeof(sdb_plugin_collector_cb_t),
sdb_plugin_cb_init,
- sdb_plugin_cb_destroy,
- /* clone = */ NULL
+ sdb_plugin_cb_destroy
};
static int
lt_dlhandle lh;
int (*mod_init)(sdb_plugin_info_t *);
- sdb_plugin_info_t plugin_info = SDB_PLUGIN_INFO_INIT;
+ sdb_plugin_info_t info = SDB_PLUGIN_INFO_INIT;
int status;
return -1;
}
- status = mod_init(&plugin_info);
+ status = mod_init(&info);
if (status) {
sdb_log(SDB_LOG_ERR, "plugin: Failed to initialize "
"plugin '%s'", name);
+ sdb_plugin_info_clear(&info);
return -1;
}
/* compare minor version */
- if ((plugin_info.version < 0)
- || ((int)(plugin_info.version / 100) != (int)(SDB_VERSION / 100)))
+ if ((info.version < 0)
+ || ((int)(info.version / 100) != (int)(SDB_VERSION / 100)))
sdb_log(SDB_LOG_WARNING, "plugin: WARNING: version of "
"plugin '%s' (%i.%i.%i) does not match our version "
"(%i.%i.%i); this might cause problems",
- name, SDB_VERSION_DECODE(plugin_info.version),
+ name, SDB_VERSION_DECODE(info.version),
SDB_VERSION_DECODE(SDB_VERSION));
sdb_log(SDB_LOG_INFO, "plugin: Successfully loaded "
- "plugin '%s' v%i (%s)\n\t%s",
- plugin_info.name, plugin_info.plugin_version,
- plugin_info.description, plugin_info.copyright);
+ "plugin '%s' v%i (%s)\n\t%s\n\tLicense: %s",
+ INFO_GET(&info, name), info.plugin_version,
+ INFO_GET(&info, description),
+ INFO_GET(&info, copyright),
+ INFO_GET(&info, license));
+ sdb_plugin_info_clear(&info);
return 0;
} /* sdb_plugin_load */
case SDB_PLUGIN_INFO_NAME:
{
char *name = va_arg(ap, char *);
- info->name = name;
+ if (name) {
+ if (info->name)
+ free(info->name);
+ info->name = strdup(name);
+ }
}
break;
case SDB_PLUGIN_INFO_DESC:
{
char *desc = va_arg(ap, char *);
- info->description = desc;
+ if (desc) {
+ if (info->description)
+ free(info->description);
+ info->description = strdup(desc);
+ }
}
break;
case SDB_PLUGIN_INFO_COPYRIGHT:
{
char *copyright = va_arg(ap, char *);
- info->copyright = copyright;
+ if (copyright)
+ info->copyright = strdup(copyright);
}
break;
case SDB_PLUGIN_INFO_LICENSE:
{
char *license = va_arg(ap, char *);
- info->license = license;
+ if (license) {
+ if (info->license)
+ free(info->license);
+ info->license = strdup(license);
+ }
}
break;
case SDB_PLUGIN_INFO_VERSION:
user_data);
} /* sdb_plugin_register_log */
+int
+sdb_plugin_register_cname(const char *name, sdb_plugin_cname_cb callback,
+ sdb_object_t *user_data)
+{
+ return sdb_plugin_add_callback(&cname_list, "cname", name, callback,
+ user_data);
+} /* sdb_plugin_register_cname */
+
int
sdb_plugin_register_collector(const char *name, sdb_plugin_collector_cb callback,
const sdb_time_t *interval, sdb_object_t *user_data)
@@ -471,36 +539,36 @@ sdb_plugin_register_collector(const char *name, sdb_plugin_collector_cb callback
sdb_plugin_ctx_t
sdb_plugin_get_ctx(void)
{
- sdb_plugin_ctx_t *ctx;
+ ctx_t *ctx;
if (! plugin_ctx_key_initialized)
- sdb_plugin_ctx_init();
+ ctx_key_init();
ctx = pthread_getspecific(plugin_ctx_key);
if (! ctx)
- ctx = sdb_plugin_ctx_create();
+ ctx = ctx_create();
if (! ctx)
return plugin_default_ctx;
- return *ctx;
+ return ctx->public;
} /* sdb_plugin_get_ctx */
sdb_plugin_ctx_t
sdb_plugin_set_ctx(sdb_plugin_ctx_t ctx)
{
- sdb_plugin_ctx_t *tmp;
+ ctx_t *tmp;
sdb_plugin_ctx_t old;
if (! plugin_ctx_key_initialized)
- sdb_plugin_ctx_init();
+ ctx_key_init();
tmp = pthread_getspecific(plugin_ctx_key);
if (! tmp)
- tmp = sdb_plugin_ctx_create();
+ tmp = ctx_create();
if (! tmp)
return plugin_default_ctx;
- old = *tmp;
- *tmp = ctx;
+ old = tmp->public;
+ tmp->public = ctx;
return old;
} /* sdb_plugin_set_ctx */
return 0;
} /* sdb_plugin_read_loop */
+char *
+sdb_plugin_cname(char *hostname)
+{
+ sdb_llist_iter_t *iter;
+
+ if (! hostname)
+ return NULL;
+
+ if (! cname_list)
+ return hostname;
+
+ iter = sdb_llist_get_iter(cname_list);
+ while (sdb_llist_iter_has_next(iter)) {
+ sdb_plugin_cname_cb callback;
+ char *cname;
+
+ sdb_object_t *obj = sdb_llist_iter_get_next(iter);
+ assert(obj);
+
+ callback = SDB_PLUGIN_CB(obj)->cb_callback;
+ cname = callback(hostname, SDB_PLUGIN_CB(obj)->cb_user_data);
+ if (cname) {
+ free(hostname);
+ hostname = cname;
+ }
+ /* else: don't change hostname */
+ }
+ sdb_llist_iter_destroy(iter);
+ return hostname;
+} /* sdb_plugin_cname */
+
int
sdb_plugin_log(int prio, const char *msg)
{