Merged autotools changes (configure.in, src/plugin.c, src/Makefile.am, Makefile.am...
[collectd.git] / src / plugin.c
1 #include "collectd.h"
2
3 #include <ltdl.h>
4
5 #include "plugin.h"
6 #include "multicast.h"
7
8 typedef struct plugin
9 {
10         char *type;
11         void (*init) (void);
12         void (*read) (void);
13         void (*write) (char *host, char *inst, char *val);
14         struct plugin *next;
15 } plugin_t;
16
17 static plugin_t *first_plugin = NULL;
18
19 #ifdef HAVE_LIBRRD
20 extern int operating_mode;
21 #endif
22
23 /*
24  * Returns the number of plugins registered
25  */
26 int plugin_count (void)
27 {
28         int i;
29         plugin_t *p;
30
31         for (i = 0, p = first_plugin; p != NULL; p = p->next)
32                 i++;
33
34         return (i);
35 }
36
37 /*
38  * Returns the plugins with the type `type' or NULL if it's not found.
39  */
40 plugin_t *plugin_search (char *type)
41 {
42         plugin_t *ret;
43
44         if (type == NULL)
45                 return (NULL);
46
47         for (ret = first_plugin; ret != NULL; ret = ret->next)
48                 if (strcmp (ret->type, type) == 0)
49                         break;
50
51         return (ret);
52 }
53
54 /*
55  * (Try to) load the shared object `name'. Won't complain if it isn't a shared
56  * object, but it will bitch about a shared object not having a
57  * ``module_register'' symbol..
58  */
59 void plugin_load (char *name)
60 {
61         lt_dlhandle dlh;
62         void (*reg_handle) (void);
63
64         lt_dlinit ();
65         lt_dlerror (); /* clear errors */
66
67         if ((dlh = lt_dlopen (name)) == NULL)
68                 return;
69
70         if ((reg_handle = lt_dlsym (dlh, "module_register")) == NULL)
71         {
72                 syslog (LOG_WARNING, "Couldn't find symbol ``module_register'' in ``%s'': %s\n",
73                                 name, lt_dlerror ());
74                 lt_dlclose (dlh);
75                 return;
76         }
77
78         (*reg_handle) ();
79 }
80
81 /*
82  * (Try to) load all plugins in `dir'. Returns the number of loaded plugins..
83  */
84 #define BUFSIZE 512
85 int plugin_load_all (char *dir)
86 {
87         DIR *dh;
88         struct dirent *de;
89         char filename[BUFSIZE];
90         struct stat statbuf;
91
92         if (dir == NULL)
93                 dir = PLUGINDIR;
94
95         if ((dh = opendir (dir)) == NULL)
96         {
97                 fprintf (stderr, "Error: Cannot read plugin directory `%s'\n", dir);
98                 return (0);
99         }
100
101         while ((de = readdir (dh)) != NULL)
102         {
103                 if (snprintf (filename, BUFSIZE, "%s/%s", dir, de->d_name) >= BUFSIZE)
104                         continue;
105
106                 if (lstat (filename, &statbuf) == -1)
107                 {
108                         syslog (LOG_WARNING, "stat %s: %s", filename, strerror (errno));
109                         continue;
110                 }
111                 else if (!S_ISREG (statbuf.st_mode))
112                 {
113                         continue;
114                 }
115
116                 plugin_load (filename);
117         }
118
119         closedir (dh);
120
121         return (plugin_count ());
122 }
123 #undef BUFSIZE
124
125 /*
126  * Call `init' on all plugins (if given)
127  */
128 void plugin_init_all (void)
129 {
130         plugin_t *p;
131
132         for (p = first_plugin; p != NULL; p = p->next)
133                 if (p->init != NULL)
134                         (*p->init) ();
135 }
136
137 /*
138  * Call `read' on all plugins (if given)
139  */
140 void plugin_read_all (void)
141 {
142         plugin_t *p;
143
144         for (p = first_plugin; p != NULL; p = p->next)
145                 if (p->read != NULL)
146                         (*p->read) ();
147 }
148
149 /*
150  * Add plugin to the linked list of registered plugins.
151  */
152 void plugin_register (char *type,
153                 void (*init) (void),
154                 void (*read) (void),
155                 void (*write) (char *, char *, char *))
156 {
157         plugin_t *p;
158
159         if (plugin_search (type) != NULL)
160                 return;
161
162         if ((p = (plugin_t *) malloc (sizeof (plugin_t))) == NULL)
163                 return;
164
165         if ((p->type = strdup (type)) == NULL)
166         {
167                 free (p);
168                 return;
169         }
170
171         p->init  = init;
172         p->read  = read;
173         p->write = write;
174
175         p->next = first_plugin;
176         first_plugin = p;
177 }
178
179 /*
180  * Send received data back to the plugin/module which will append DS
181  * definitions and pass it on to ``rrd_update_file''.
182  */
183 #ifdef HAVE_LIBRRD
184 void plugin_write (char *host, char *type, char *inst, char *val)
185 {
186         plugin_t *p;
187
188         if ((p = plugin_search (type)) == NULL)
189                 return;
190
191         if (p->write == NULL)
192                 return;
193
194         (*p->write) (host, inst, val);
195 }
196 #endif /* HAVE_LIBRRD */
197
198 /*
199  * Receive data from the plugin/module and get it somehow to ``plugin_write'':
200  * Either using ``multicast_send'' (when in network/client mode) or call it
201  * directly (in local mode).
202  */
203 void plugin_submit (char *type, char *inst, char *val)
204 {
205 #ifdef HAVE_LIBRRD
206         if (operating_mode == MODE_LOCAL)
207                 plugin_write (NULL, type, inst, val);
208         else if (operating_mode == MODE_CLIENT)
209                 multicast_send (type, inst, val);
210         else /* operating_mode == MODE_SERVER */
211                 syslog (LOG_ERR, "WTF is the server doing in ``plugin_submit''?!?\n");
212 #else
213         multicast_send (type, inst, val);
214 #endif
215 }