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