2 Bacula® - The Network Backup Solution
4 Copyright (C) 2007-2011 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 three of the GNU Affero 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 Affero 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 Kern Sibbald.
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 "sd_plugins.h"
38 const int dbglvl = 50;
39 const char *plugin_type = "-sd.so";
42 /* Forward referenced functions */
43 static bRC baculaGetValue(bpContext *ctx, bsdrVariable var, void *value);
44 static bRC baculaSetValue(bpContext *ctx, bsdwVariable var, void *value);
45 static bRC baculaRegisterEvents(bpContext *ctx, ...);
46 static bRC baculaJobMsg(bpContext *ctx, const char *file, int line,
47 int type, utime_t mtime, const char *fmt, ...);
48 static bRC baculaDebugMsg(bpContext *ctx, const char *file, int line,
49 int level, const char *fmt, ...);
50 static char *baculaEditDeviceCodes(DCR *dcr, char *omsg,
51 const char *imsg, const char *cmd);
55 static bsdInfo binfo = {
57 SD_PLUGIN_INTERFACE_VERSION
60 /* Bacula entry points */
61 static bsdFuncs bfuncs = {
63 SD_PLUGIN_INTERFACE_VERSION,
73 * Bacula private context
76 JCR *jcr; /* jcr for plugin */
77 bRC rc; /* last return code */
78 bool disabled; /* set if plugin disabled */
81 static bool is_plugin_disabled(bpContext *plugin_ctx)
87 b_ctx = (bacula_ctx *)plugin_ctx->bContext;
88 return b_ctx->disabled;
92 static bool is_plugin_disabled(JCR *jcr)
94 return is_plugin_disabled(jcr->plugin_ctx);
99 * Create a plugin event
101 int generate_plugin_event(JCR *jcr, bsdEventType eventType, void *value)
103 bpContext *plugin_ctx;
109 if (!bplugin_list || !jcr || !jcr->plugin_ctx_list) {
110 return bRC_OK; /* Return if no plugins loaded */
112 if (jcr->is_job_canceled()) {
116 bpContext *plugin_ctx_list = (bpContext *)jcr->plugin_ctx_list;
117 event.eventType = eventType;
119 Dmsg2(dbglvl, "sd-plugin_ctx_list=%p JobId=%d\n", jcr->plugin_ctx_list, jcr->JobId);
121 foreach_alist(plugin, bplugin_list) {
122 plugin_ctx = &plugin_ctx_list[i++];
123 if (is_plugin_disabled(plugin_ctx)) {
126 rc = sdplug_func(plugin)->handlePluginEvent(plugin_ctx, &event, value);
135 static void dump_sd_plugin(Plugin *plugin, FILE *fp)
140 psdInfo *info = (psdInfo *) plugin->pinfo;
141 fprintf(fp, "\tversion=%d\n", info->version);
142 fprintf(fp, "\tdate=%s\n", NPRTB(info->plugin_date));
143 fprintf(fp, "\tmagic=%s\n", NPRTB(info->plugin_magic));
144 fprintf(fp, "\tauthor=%s\n", NPRTB(info->plugin_author));
145 fprintf(fp, "\tlicence=%s\n", NPRTB(info->plugin_license));
146 fprintf(fp, "\tversion=%s\n", NPRTB(info->plugin_version));
147 fprintf(fp, "\tdescription=%s\n", NPRTB(info->plugin_description));
150 void load_sd_plugins(const char *plugin_dir)
152 Dmsg0(dbglvl, "Load sd plugins\n");
154 Dmsg0(dbglvl, "No sd plugin dir!\n");
157 bplugin_list = New(alist(10, not_owned_by_alist));
158 load_plugins((void *)&binfo, (void *)&bfuncs, plugin_dir, plugin_type, NULL);
159 Dmsg1(dbglvl, "num plugins=%d\n", bplugin_list->size());
160 dbg_plugin_add_hook(dump_sd_plugin);
164 * Create a new instance of each plugin for this Job
166 void new_plugins(JCR *jcr)
171 Dmsg0(dbglvl, "=== enter new_plugins ===\n");
173 Dmsg0(dbglvl, "No sd plugin list!\n");
176 if (jcr->is_job_canceled()) {
180 int num = bplugin_list->size();
182 Dmsg1(dbglvl, "sd-plugin-list size=%d\n", num);
187 jcr->plugin_ctx_list = (bpContext *)malloc(sizeof(bpContext) * num);
189 bpContext *plugin_ctx_list = jcr->plugin_ctx_list;
190 Dmsg2(dbglvl, "Instantiate sd-plugin_ctx_list=%p JobId=%d\n", jcr->plugin_ctx_list, jcr->JobId);
191 foreach_alist(plugin, bplugin_list) {
192 /* Start a new instance of each plugin */
193 bacula_ctx *b_ctx = (bacula_ctx *)malloc(sizeof(bacula_ctx));
194 memset(b_ctx, 0, sizeof(bacula_ctx));
196 plugin_ctx_list[i].bContext = (void *)b_ctx;
197 plugin_ctx_list[i].pContext = NULL;
198 if (sdplug_func(plugin)->newPlugin(&plugin_ctx_list[i++]) != bRC_OK) {
199 b_ctx->disabled = true;
205 * Free the plugin instances for this Job
207 void free_plugins(JCR *jcr)
216 bpContext *plugin_ctx_list = (bpContext *)jcr->plugin_ctx_list;
217 Dmsg2(dbglvl, "Free instance sd-plugin_ctx_list=%p JobId=%d\n", jcr->plugin_ctx_list, jcr->JobId);
218 foreach_alist(plugin, bplugin_list) {
219 /* Free the plugin instance */
220 sdplug_func(plugin)->freePlugin(&plugin_ctx_list[i++]);
222 free(plugin_ctx_list);
223 jcr->plugin_ctx_list = NULL;
227 /* ==============================================================
229 * Callbacks from the plugin
231 * ==============================================================
233 static bRC baculaGetValue(bpContext *ctx, bsdrVariable var, void *value)
239 jcr = ((bacula_ctx *)ctx->bContext)->jcr;
248 *((int *)value) = jcr->JobId;
249 Dmsg1(dbglvl, "sd-plugin: return bVarJobId=%d\n", jcr->JobId);
252 *((char **)value) = jcr->Job;
253 Dmsg1(dbglvl, "Bacula: return Job name=%s\n", jcr->Job);
261 static bRC baculaSetValue(bpContext *ctx, bsdwVariable var, void *value)
264 if (!value || !ctx) {
267 // Dmsg1(dbglvl, "bacula: baculaGetValue var=%d\n", var);
268 jcr = ((bacula_ctx *)ctx->bContext)->jcr;
272 // Dmsg1(dbglvl, "Bacula: jcr=%p\n", jcr);
273 /* Nothing implemented yet */
274 Dmsg1(dbglvl, "sd-plugin: baculaSetValue var=%d\n", var);
278 static bRC baculaRegisterEvents(bpContext *ctx, ...)
284 while ((event = va_arg(args, uint32_t))) {
285 Dmsg1(dbglvl, "sd-Plugin wants event=%u\n", event);
291 static bRC baculaJobMsg(bpContext *ctx, const char *file, int line,
292 int type, utime_t mtime, const char *fmt, ...)
299 jcr = ((bacula_ctx *)ctx->bContext)->jcr;
304 va_start(arg_ptr, fmt);
305 bvsnprintf(buf, sizeof(buf), fmt, arg_ptr);
307 Jmsg(jcr, type, mtime, "%s", buf);
311 static bRC baculaDebugMsg(bpContext *ctx, const char *file, int line,
312 int level, const char *fmt, ...)
317 va_start(arg_ptr, fmt);
318 bvsnprintf(buf, sizeof(buf), fmt, arg_ptr);
320 d_msg(file, line, level, "%s", buf);
324 static char *baculaEditDeviceCodes(DCR *dcr, char *omsg,
325 const char *imsg, const char *cmd)
327 return edit_device_codes(dcr, omsg, imsg, cmd);
332 int main(int argc, char *argv[])
334 char plugin_dir[1000];
339 strcpy(my_name, "test-dir");
341 getcwd(plugin_dir, sizeof(plugin_dir)-1);
342 load_sd_plugins(plugin_dir);
350 generate_plugin_event(jcr1, bsdEventJobStart, (void *)"Start Job 1");
351 generate_plugin_event(jcr1, bsdEventJobEnd);
352 generate_plugin_event(jcr2, bsdEventJobStart, (void *)"Start Job 1");
354 generate_plugin_event(jcr2, bsdEventJobEnd);
359 Dmsg0(dbglvl, "sd-plugin: OK ...\n");
365 #endif /* TEST_PROGRAM */