]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/dird/dir_plugins.c
b2487543da872f460a64cd23e05ecb4dc7bdc5d8
[bacula/bacula] / bacula / src / dird / dir_plugins.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2007-2008 Free Software Foundation Europe e.V.
5
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.
12
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.
17
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
21    02110-1301, USA.
22
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.
27 */
28 /*
29  * Main program to test loading and running Bacula plugins.
30  *   Destined to become Bacula pluginloader, ...
31  *
32  * Kern Sibbald, October 2007
33  */
34 #include "bacula.h"
35 #include "dird.h"
36
37 const int dbglvl = 0;
38 const char *plugin_type = "-dir.so";
39
40
41 /* Forward referenced functions */
42 static bRC baculaGetValue(bpContext *ctx, brVariable var, void *value);
43 static bRC baculaSetValue(bpContext *ctx, bwVariable var, void *value);
44 static bRC baculaRegisterEvents(bpContext *ctx, ...);
45 static bRC baculaJobMsg(bpContext *ctx, const char *file, int line,
46   int type, time_t mtime, const char *msg);
47 static bRC baculaDebugMsg(bpContext *ctx, const char *file, int line,
48   int level, const char *msg);
49
50
51 /* Bacula info */
52 static bInfo binfo = {
53    sizeof(bFuncs),
54    DIR_PLUGIN_INTERFACE_VERSION,
55 };
56
57 /* Bacula entry points */
58 static bFuncs bfuncs = {
59    sizeof(bFuncs),
60    DIR_PLUGIN_INTERFACE_VERSION,
61    baculaRegisterEvents,
62    baculaGetValue,
63    baculaSetValue,
64    baculaJobMsg,
65    baculaDebugMsg
66 };
67
68 /*
69  * Create a plugin event 
70  */
71 void generate_plugin_event(JCR *jcr, bEventType eventType, void *value)
72 {
73    bEvent event;
74    Plugin *plugin;
75    int i = 0;
76
77    if (!plugin_list) {
78       return;
79    }
80
81    bpContext *plugin_ctx_list = (bpContext *)jcr->plugin_ctx_list;
82    event.eventType = eventType;
83
84    Dmsg2(dbglvl, "plugin_ctx_list=%p JobId=%d\n", jcr->plugin_ctx_list, jcr->JobId);
85
86    foreach_alist(plugin, plugin_list) {
87       bRC rc;
88       rc = plug_func(plugin)->handlePluginEvent(&plugin_ctx_list[i++], &event, value);
89       if (rc != bRC_OK) {
90          break;
91       }
92    }
93
94    return;
95 }
96
97 static void dump_dir_plugin(Plugin *plugin, FILE *fp)
98 {
99    if (!plugin) {
100       return ;
101    }
102    pInfo *info = (pInfo *) plugin->pinfo;
103    fprintf(fp, "\tversion=%d\n", info->version);
104    fprintf(fp, "\tdate=%s\n", NPRTB(info->plugin_date));
105    fprintf(fp, "\tmagic=%s\n", NPRTB(info->plugin_magic));
106    fprintf(fp, "\tauthor=%s\n", NPRTB(info->plugin_author));
107    fprintf(fp, "\tlicence=%s\n", NPRTB(info->plugin_license));
108    fprintf(fp, "\tversion=%s\n", NPRTB(info->plugin_version));
109    fprintf(fp, "\tdescription=%s\n", NPRTB(info->plugin_description));
110 }
111
112 void load_dir_plugins(const char *plugin_dir)
113 {
114    if (!plugin_dir) {
115       return;
116    }
117
118    plugin_list = New(alist(10, not_owned_by_alist));
119    load_plugins((void *)&binfo, (void *)&bfuncs, plugin_dir, plugin_type);
120    dbg_plugin_add_hook(dump_dir_plugin);
121 }
122
123 /*
124  * Create a new instance of each plugin for this Job
125  */
126 void new_plugins(JCR *jcr)
127 {
128    Plugin *plugin;
129    int i = 0;
130
131    if (!plugin_list) {
132       return;
133    }
134
135    int num = plugin_list->size();
136
137    if (num == 0) {
138       return;
139    }
140
141    jcr->plugin_ctx_list = (bpContext *)malloc(sizeof(bpContext) * num);
142
143    bpContext *plugin_ctx_list = jcr->plugin_ctx_list;
144    Dmsg2(dbglvl, "Instantiate plugin_ctx_list=%p JobId=%d\n", jcr->plugin_ctx_list, jcr->JobId);
145    foreach_alist(plugin, plugin_list) {
146       /* Start a new instance of each plugin */
147       plugin_ctx_list[i].bContext = (void *)jcr;
148       plugin_ctx_list[i].pContext = NULL;
149       plug_func(plugin)->newPlugin(&plugin_ctx_list[i++]);
150    }
151 }
152
153 /*
154  * Free the plugin instances for this Job
155  */
156 void free_plugins(JCR *jcr)
157 {
158    Plugin *plugin;
159    int i = 0;
160
161    if (!plugin_list) {
162       return;
163    }
164
165    bpContext *plugin_ctx_list = (bpContext *)jcr->plugin_ctx_list;
166    Dmsg2(dbglvl, "Free instance plugin_ctx_list=%p JobId=%d\n", jcr->plugin_ctx_list, jcr->JobId);
167    foreach_alist(plugin, plugin_list) {
168       /* Free the plugin instance */
169       plug_func(plugin)->freePlugin(&plugin_ctx_list[i++]);
170    }
171    free(plugin_ctx_list);
172    jcr->plugin_ctx_list = NULL;
173 }
174
175 /* ==============================================================
176  *
177  * Callbacks from the plugin
178  *
179  * ==============================================================
180  */
181 static bRC baculaGetValue(bpContext *ctx, brVariable var, void *value)
182 {
183    JCR *jcr = (JCR *)(ctx->bContext);
184 // Dmsg1(dbglvl, "bacula: baculaGetValue var=%d\n", var);
185    if (!value) {
186       return bRC_Error;
187    }
188 // Dmsg1(dbglvl, "Bacula: jcr=%p\n", jcr); 
189    switch (var) {
190    case bVarJobId:
191       *((int *)value) = jcr->JobId;
192       Dmsg1(dbglvl, "Bacula: return bVarJobId=%d\n", jcr->JobId);
193       break;
194    default:
195       break;
196    }
197    return bRC_OK;
198 }
199
200 static bRC baculaSetValue(bpContext *ctx, bwVariable var, void *value)
201 {
202    Dmsg1(dbglvl, "bacula: baculaSetValue var=%d\n", var);
203    return bRC_OK;
204 }
205
206 static bRC baculaRegisterEvents(bpContext *ctx, ...)
207 {
208    va_list args;
209    uint32_t event;
210
211    va_start(args, ctx);
212    while ((event = va_arg(args, uint32_t))) {
213       Dmsg1(dbglvl, "Plugin wants event=%u\n", event);
214    }
215    va_end(args);
216    return bRC_OK;
217 }
218
219 static bRC baculaJobMsg(bpContext *ctx, const char *file, int line,
220   int type, time_t mtime, const char *msg)
221 {
222    Dmsg5(dbglvl, "Job message: %s:%d type=%d time=%ld msg=%s\n",
223       file, line, type, mtime, msg);
224    return bRC_OK;
225 }
226
227 static bRC baculaDebugMsg(bpContext *ctx, const char *file, int line,
228   int level, const char *msg)
229 {
230    Dmsg4(dbglvl, "Debug message: %s:%d level=%d msg=%s\n",
231       file, line, level, msg);
232    return bRC_OK;
233 }
234
235 #ifdef TEST_PROGRAM
236
237
238 int main(int argc, char *argv[])
239 {
240    char plugin_dir[1000];
241    JCR mjcr1, mjcr2;
242    JCR *jcr1 = &mjcr1;
243    JCR *jcr2 = &mjcr2;
244
245    strcpy(my_name, "test-dir");
246     
247    getcwd(plugin_dir, sizeof(plugin_dir)-1);
248    load_dir_plugins(plugin_dir);
249
250    jcr1->JobId = 111;
251    new_plugins(jcr1);
252
253    jcr2->JobId = 222;
254    new_plugins(jcr2);
255
256    generate_plugin_event(jcr1, bEventJobStart, (void *)"Start Job 1");
257    generate_plugin_event(jcr1, bEventJobEnd);
258    generate_plugin_event(jcr2, bEventJobStart, (void *)"Start Job 1");
259    free_plugins(jcr1);
260    generate_plugin_event(jcr2, bEventJobEnd);
261    free_plugins(jcr2);
262
263    unload_plugins();
264
265    Dmsg0(dbglvl, "bacula: OK ...\n");
266    close_memory_pool();
267    sm_dump(false);
268    return 0;
269 }
270
271 #endif /* TEST_PROGRAM */