]> git.itanic.dy.fi Git - rrdd/blob - plugin_manager.c
onewire_parser: Implement simultaneous reading
[rrdd] / plugin_manager.c
1 #include <stdlib.h>
2 #include <dlfcn.h>
3 #include <string.h>
4 #include <libgen.h>
5
6 #include "plugin_manager.h"
7 #include "plugin.h"
8 #include "debug.h"
9 #include "version.h"
10
11 static char *exec_path;
12
13 int init_plugin_manager(const char *_exec_path)
14 {
15         char *str = strdup(_exec_path);
16         exec_path = strdup(dirname(str));
17
18         free(str);
19         return 0;
20 }
21
22 int load_plugin(const char *path)
23 {
24         struct plugin_info *info;
25         void *handle;
26         int ret = -1;
27
28         handle = dlopen(path, RTLD_NOW);
29         if (!handle) {
30                 pr_err("Failed to load plugin %s: %s\n", path, dlerror());
31                 return -1;
32         }
33
34         info = dlsym(handle, "plugin_info");
35         if (!info) {
36                 pr_err("Plugin %s does not contain plugin info\n", path);
37                 goto out;
38         }
39
40         if (!info->version) {
41                 pr_err("Plugin %s version info missing\n", path);
42                 ret = -1;
43                 goto out;
44         }
45
46         if (strcmp(RRDD_VERSION, info->version)) {
47                 pr_err("Plugin %s version mismatch, expected %s, got %s\n",
48                         path, RRDD_VERSION, info->version);
49                 ret = -1;
50                 goto out;
51         }
52
53         if (!info->init) {
54                 pr_err("Plugin info structure has NULL .init callback\n");
55                 goto out;
56         }
57
58         ret = info->init();
59         pr_info("Loading plugin %s %s\n", path,
60                 ret ? "failed" : "succeeded");
61
62 out:
63         if (ret)
64                 dlclose(handle);
65
66         return ret;
67 }
68
69 /*
70  * Try to load a parser plugin with file name matching some of the
71  * following candidates (%s being the requested name):
72  *
73  * "%s_parser.so"
74  * "./%s_parser.so"
75  * "<exec_path>/%s_parser.so"
76  */
77 int load_parser_plugin(const char *name)
78 {
79         char str[256], parser[] = "_parser.so";
80         int ret;
81
82         strncpy(str, name, sizeof(str));
83         str[sizeof(str) - 1] = '\0';
84         strncat(str, parser, sizeof(str) - strlen(str) - 1);
85         ret = load_plugin(str);
86         if (!ret)
87                 return 0;
88
89         strncpy(str, "./", sizeof(str));
90         str[sizeof(str) - 1] = '\0';
91         strncat(str, name, sizeof(str) - strlen(str) - 1);
92         strncat(str, parser, sizeof(str) - strlen(str) - 1);
93         ret = load_plugin(str);
94         if (!ret)
95                 return 0;
96
97         if (!exec_path)
98                 return 0;
99
100         strncpy(str, exec_path, sizeof(str));
101         str[sizeof(str) - 1] = '\0';
102         strncat(str, "/", sizeof(str) - strlen(str) - 1);
103         strncat(str, name, sizeof(str) - strlen(str) - 1);
104         strncat(str, parser, sizeof(str) - strlen(str) - 1);
105         return load_plugin(str);
106 }