CFLAGS=-Wall -O2 -g
RRDD_OBJS= main.o process.o rrdtool.o parser.o string.o \
- debug.o config.o onewire_parser.o
+ debug.o config.o onewire_parser.o plugin_manager.o
ALL_OBJS = $(RRDD_OBJS)
ALL_DEBS = $(patsubst %.o,.%.o.d,$(ALL_OBJS))
all: rrdd
rrdd: $(RRDD_OBJS)
- $(QUIET_LINK)$(CC) -o rrdd $(RRDD_OBJS) -lconfig -lownet
+ $(QUIET_LINK)$(CC) -o rrdd $(RRDD_OBJS) -lconfig -lownet -ldl -rdynamic
clean:
rm -vf rrdd *~ *.o .*.d
--- /dev/null
+#ifndef _PLUGIN_H
+#define _PLUGIN_H
+
+typedef int (plugin_init_fn_t)(void);
+
+struct plugin_info {
+ /* Name of the plugin, used in debug prints */
+ const char *name;
+
+ /* This gets executed once the plugin is loaded */
+ plugin_init_fn_t *init;
+};
+
+#endif
--- /dev/null
+#include <dlfcn.h>
+
+#include "plugin_manager.h"
+#include "plugin.h"
+#include "debug.h"
+
+int load_plugin(const char *path)
+{
+ struct plugin_info *info;
+ void *handle;
+ int ret = -1;
+
+ handle = dlopen(path, RTLD_NOW);
+ if (!handle) {
+ pr_err("Failed to load plugin %s: %s\n", path, dlerror());
+ return -1;
+ }
+
+ info = dlsym(handle, "plugin_info");
+ if (!info) {
+ pr_err("Plugin %s does not contain plugin info\n", path);
+ goto out;
+ }
+
+ if (!info->init) {
+ pr_err("Plugin info structure has NULL .init callback\n");
+ goto out;
+ }
+
+ ret = info->init();
+ pr_info("Loading plugin %s %s\n", path,
+ ret ? "failed" : "succeeded");
+
+out:
+ if (ret)
+ dlclose(handle);
+
+ return ret;
+}
--- /dev/null
+#ifndef _PLUGIN_MANAGER_H
+#define _PLUGIN_MANAGER_H
+
+int load_plugin(const char *path);
+
+#endif