]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/dird/dir_plugins.c
kes Change Bacula trademark owner from John Walker to Kern Sibbald
[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 void load_dir_plugins(const char *plugin_dir)
98 {
99    if (!plugin_dir) {
100       return;
101    }
102
103    plugin_list = New(alist(10, not_owned_by_alist));
104    load_plugins((void *)&binfo, (void *)&bfuncs, plugin_dir, plugin_type);
105 }
106
107 /*
108  * Create a new instance of each plugin for this Job
109  */
110 void new_plugins(JCR *jcr)
111 {
112    Plugin *plugin;
113    int i = 0;
114
115    if (!plugin_list) {
116       return;
117    }
118
119    int num = plugin_list->size();
120
121    if (num == 0) {
122       return;
123    }
124
125    jcr->plugin_ctx_list = (void *)malloc(sizeof(bpContext) * num);
126
127    bpContext *plugin_ctx_list = (bpContext *)jcr->plugin_ctx_list;
128    Dmsg2(dbglvl, "Instantiate plugin_ctx_list=%p JobId=%d\n", jcr->plugin_ctx_list, jcr->JobId);
129    foreach_alist(plugin, plugin_list) {
130       /* Start a new instance of each plugin */
131       plugin_ctx_list[i].bContext = (void *)jcr;
132       plugin_ctx_list[i].pContext = NULL;
133       plug_func(plugin)->newPlugin(&plugin_ctx_list[i++]);
134    }
135 }
136
137 /*
138  * Free the plugin instances for this Job
139  */
140 void free_plugins(JCR *jcr)
141 {
142    Plugin *plugin;
143    int i = 0;
144
145    if (!plugin_list) {
146       return;
147    }
148
149    bpContext *plugin_ctx_list = (bpContext *)jcr->plugin_ctx_list;
150    Dmsg2(dbglvl, "Free instance plugin_ctx_list=%p JobId=%d\n", jcr->plugin_ctx_list, jcr->JobId);
151    foreach_alist(plugin, plugin_list) {
152       /* Free the plugin instance */
153       plug_func(plugin)->freePlugin(&plugin_ctx_list[i++]);
154    }
155    free(plugin_ctx_list);
156    jcr->plugin_ctx_list = NULL;
157 }
158
159
160 /* ==============================================================
161  *
162  * Callbacks from the plugin
163  *
164  * ==============================================================
165  */
166 static bRC baculaGetValue(bpContext *ctx, brVariable var, void *value)
167 {
168    JCR *jcr = (JCR *)(ctx->bContext);
169 // Dmsg1(dbglvl, "bacula: baculaGetValue var=%d\n", var);
170    if (!value) {
171       return bRC_Error;
172    }
173 // Dmsg1(dbglvl, "Bacula: jcr=%p\n", jcr); 
174    switch (var) {
175    case bVarJobId:
176       *((int *)value) = jcr->JobId;
177       Dmsg1(dbglvl, "Bacula: return bVarJobId=%d\n", jcr->JobId);
178       break;
179    default:
180       break;
181    }
182    return bRC_OK;
183 }
184
185 static bRC baculaSetValue(bpContext *ctx, bwVariable var, void *value)
186 {
187    Dmsg1(dbglvl, "bacula: baculaSetValue var=%d\n", var);
188    return bRC_OK;
189 }
190
191 static bRC baculaRegisterEvents(bpContext *ctx, ...)
192 {
193    va_list args;
194    uint32_t event;
195
196    va_start(args, ctx);
197    while ((event = va_arg(args, uint32_t))) {
198       Dmsg1(dbglvl, "Plugin wants event=%u\n", event);
199    }
200    va_end(args);
201    return bRC_OK;
202 }
203
204 static bRC baculaJobMsg(bpContext *ctx, const char *file, int line,
205   int type, time_t mtime, const char *msg)
206 {
207    Dmsg5(dbglvl, "Job message: %s:%d type=%d time=%ld msg=%s\n",
208       file, line, type, mtime, msg);
209    return bRC_OK;
210 }
211
212 static bRC baculaDebugMsg(bpContext *ctx, const char *file, int line,
213   int level, const char *msg)
214 {
215    Dmsg4(dbglvl, "Debug message: %s:%d level=%d msg=%s\n",
216       file, line, level, msg);
217    return bRC_OK;
218 }
219
220 #ifdef TEST_PROGRAM
221
222
223 int main(int argc, char *argv[])
224 {
225    char plugin_dir[1000];
226    JCR mjcr1, mjcr2;
227    JCR *jcr1 = &mjcr1;
228    JCR *jcr2 = &mjcr2;
229
230    strcpy(my_name, "test-dir");
231     
232    getcwd(plugin_dir, sizeof(plugin_dir)-1);
233    load_dir_plugins(plugin_dir);
234
235    jcr1->JobId = 111;
236    new_plugins(jcr1);
237
238    jcr2->JobId = 222;
239    new_plugins(jcr2);
240
241    generate_plugin_event(jcr1, bEventJobStart, (void *)"Start Job 1");
242    generate_plugin_event(jcr1, bEventJobEnd);
243    generate_plugin_event(jcr2, bEventJobStart, (void *)"Start Job 1");
244    free_plugins(jcr1);
245    generate_plugin_event(jcr2, bEventJobEnd);
246    free_plugins(jcr2);
247
248    unload_plugins();
249
250    Dmsg0(dbglvl, "bacula: OK ...\n");
251    close_memory_pool();
252    sm_dump(false);
253    return 0;
254 }
255
256 #endif /* TEST_PROGRAM */