2 Bacula® - The Network Backup Solution
4 Copyright (C) 2007-2008 Free Software Foundation Europe e.V.
6 The main author of Bacula is Kern Sibbald, with contributions from
7 many others, a complete list can be found in the file AUTHORS.
8 This program is Free Software; you can redistribute it and/or
9 modify it under the terms of version two of the GNU General Public
10 License as published by the Free Software Foundation, which is
11 listed in the file LICENSE.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 Bacula® is a registered trademark of John Walker.
24 The licensor of Bacula is the Free Software Foundation Europe
25 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26 Switzerland, email:ftf@fsfeurope.org.
29 * Main program to test loading and running Bacula plugins.
30 * Destined to become Bacula pluginloader, ...
32 * Kern Sibbald, October 2007
36 #include "fd-plugins.h"
38 const int dbglvl = 50;
39 const char *plugin_type = "-fd.so";
41 /* Function pointers to be set here */
42 extern int (*plugin_bopen)(JCR *jcr, const char *fname, int flags, mode_t mode);
43 extern int (*plugin_bclose)(JCR *jcr);
44 extern ssize_t (*plugin_bread)(JCR *jcr, void *buf, size_t count);
45 extern ssize_t (*plugin_bwrite)(JCR *jcr, void *buf, size_t count);
48 /* Forward referenced functions */
49 static bRC baculaGetValue(bpContext *ctx, bVariable var, void *value);
50 static bRC baculaSetValue(bpContext *ctx, bVariable var, void *value);
51 static bRC baculaRegisterEvents(bpContext *ctx, ...);
52 static bRC baculaJobMsg(bpContext *ctx, const char *file, int line,
53 int type, time_t mtime, const char *msg);
54 static bRC baculaDebugMsg(bpContext *ctx, const char *file, int line,
55 int level, const char *msg);
57 static int my_plugin_bopen(JCR *jcr, const char *fname, int flags, mode_t mode);
58 static int my_plugin_bclose(JCR *jcr);
59 static ssize_t my_plugin_bread(JCR *jcr, void *buf, size_t count);
60 static ssize_t my_plugin_bwrite(JCR *jcr, void *buf, size_t count);
64 static bInfo binfo = {
66 PLUGIN_INTERFACE_VERSION
69 /* Bacula entry points */
70 static bFuncs bfuncs = {
72 PLUGIN_INTERFACE_VERSION,
82 * Create a plugin event
84 void generate_plugin_event(JCR *jcr, bEventType eventType, void *value)
91 char *cmd = (char *)value;
97 bpContext *plugin_ctx = (bpContext *)jcr->plugin_ctx;
98 event.eventType = eventType;
100 Dmsg2(dbglvl, "plugin_ctx=%p JobId=%d\n", jcr->plugin_ctx, jcr->JobId);
101 if (eventType != bEventPluginCommand) {
102 /* Pass event to every plugin */
103 foreach_alist(plugin, plugin_list) {
104 plug_func(plugin)->handlePluginEvent(&plugin_ctx[i++], &event, value);
109 /* Handle plugin command here (backup/restore of file) */
110 if (!(p = strchr(cmd, ':'))) {
111 Jmsg1(jcr, M_ERROR, 0, "Malformed plugin command: %s\n", cmd);
116 foreach_alist(plugin, plugin_list) {
117 Dmsg3(000, "plugin=%s cmd=%s len=%d\n", plugin->file, cmd, len);
118 if (strncmp(plugin->file, cmd, len) == 0) {
119 Dmsg1(000, "Command plugin = %s\n", cmd);
120 plug_func(plugin)->handlePluginEvent(&plugin_ctx[i], &event, value);
129 void load_fd_plugins(const char *plugin_dir)
135 plugin_list = New(alist(10, not_owned_by_alist));
136 load_plugins((void *)&binfo, (void *)&bfuncs, plugin_dir, plugin_type);
137 plugin_bopen = my_plugin_bopen;
138 plugin_bclose = my_plugin_bclose;
139 plugin_bread = my_plugin_bread;
140 plugin_bwrite = my_plugin_bwrite;
145 * Create a new instance of each plugin for this Job
147 void new_plugins(JCR *jcr)
156 int num = plugin_list->size();
162 jcr->plugin_ctx = (void *)malloc(sizeof(bpContext) * num);
164 bpContext *plugin_ctx = (bpContext *)jcr->plugin_ctx;
165 Dmsg2(dbglvl, "Instantiate plugin_ctx=%p JobId=%d\n", jcr->plugin_ctx, jcr->JobId);
166 foreach_alist(plugin, plugin_list) {
167 /* Start a new instance of each plugin */
168 plugin_ctx[i].bContext = (void *)jcr;
169 plugin_ctx[i].pContext = NULL;
170 plug_func(plugin)->newPlugin(&plugin_ctx[i++]);
175 * Free the plugin instances for this Job
177 void free_plugins(JCR *jcr)
186 bpContext *plugin_ctx = (bpContext *)jcr->plugin_ctx;
187 Dmsg2(dbglvl, "Free instance plugin_ctx=%p JobId=%d\n", jcr->plugin_ctx, jcr->JobId);
188 foreach_alist(plugin, plugin_list) {
189 /* Free the plugin instance */
190 plug_func(plugin)->freePlugin(&plugin_ctx[i++]);
193 jcr->plugin_ctx = NULL;
196 static int my_plugin_bopen(JCR *jcr, const char *fname, int flags, mode_t mode)
199 Dmsg0(000, "plugin_bopen\n");
207 static int my_plugin_bclose(JCR *jcr)
210 Dmsg0(000, "plugin_bclose\n");
217 static ssize_t my_plugin_bread(JCR *jcr, void *buf, size_t count)
220 Dmsg0(000, "plugin_bread\n");
223 io.buf = (char *)buf;
227 static ssize_t my_plugin_bwrite(JCR *jcr, void *buf, size_t count)
230 Dmsg0(000, "plugin_bwrite\n");
233 io.buf = (char *)buf;
237 /* ==============================================================
239 * Callbacks from the plugin
241 * ==============================================================
243 static bRC baculaGetValue(bpContext *ctx, bVariable var, void *value)
245 JCR *jcr = (JCR *)(ctx->bContext);
246 // Dmsg1(dbglvl, "bacula: baculaGetValue var=%d\n", var);
250 // Dmsg1(dbglvl, "Bacula: jcr=%p\n", jcr);
253 *((int *)value) = jcr->JobId;
254 Dmsg1(dbglvl, "Bacula: return bVarJobId=%d\n", jcr->JobId);
257 *((char **)value) = my_name;
258 Dmsg1(dbglvl, "Bacula: return my_name=%s\n", my_name);
271 static bRC baculaSetValue(bpContext *ctx, bVariable var, void *value)
273 Dmsg1(dbglvl, "bacula: baculaSetValue var=%d\n", var);
277 static bRC baculaRegisterEvents(bpContext *ctx, ...)
283 while ((event = va_arg(args, uint32_t))) {
284 Dmsg1(dbglvl, "Plugin wants event=%u\n", event);
290 static bRC baculaJobMsg(bpContext *ctx, const char *file, int line,
291 int type, time_t mtime, const char *msg)
293 Dmsg5(dbglvl, "Job message: %s:%d type=%d time=%ld msg=%s\n",
294 file, line, type, mtime, msg);
298 static bRC baculaDebugMsg(bpContext *ctx, const char *file, int line,
299 int level, const char *msg)
301 Dmsg4(dbglvl, "Debug message: %s:%d level=%d msg=%s\n",
302 file, line, level, msg);
308 int (*plugin_bopen)(JCR *jcr, const char *fname, int flags, mode_t mode) = NULL;
309 int (*plugin_bclose)(JCR *jcr) = NULL;
310 ssize_t (*plugin_bread)(JCR *jcr, void *buf, size_t count) = NULL;
311 ssize_t (*plugin_bwrite)(JCR *jcr, void *buf, size_t count) = NULL;
314 int main(int argc, char *argv[])
316 char plugin_dir[1000];
321 strcpy(my_name, "test-fd");
323 getcwd(plugin_dir, sizeof(plugin_dir)-1);
324 load_fd_plugins(plugin_dir);
332 generate_plugin_event(jcr1, bEventJobStart);
333 generate_plugin_event(jcr1, bEventJobEnd);
334 generate_plugin_event(jcr2, bEventJobStart);
336 generate_plugin_event(jcr2, bEventJobEnd);
341 Dmsg0(dbglvl, "bacula: OK ...\n");
347 #endif /* TEST_PROGRAM */