1 /*
2 Bacula(R) - The Network Backup Solution
3
4 Copyright (C) 2000-2020 Kern Sibbald
5
6 The original author of Bacula is Kern Sibbald, with contributions
7 from many others, a complete list can be found in the file AUTHORS.
8
9 You may use this file and others of this release according to the
10 license defined in the LICENSE file, which includes the Affero General
11 Public License, v3.0 ("AGPLv3") and some additional permissions and
12 terms pursuant to its AGPLv3 Section 7.
13
14 This notice must be preserved when any source code is
15 conveyed and/or propagated.
16
17 Bacula(R) is a registered trademark of Kern Sibbald.
18 */
19 #define BUILD_PLUGIN
20 #define BUILDING_DLL /* required for Windows plugin */
21
22 #include "bacula.h"
23 #include "fd_plugins.h"
24
25 #ifdef __cplusplus
26 extern "C" {
27 #endif
28
29 #define PLUGIN_LICENSE "AGPLv3"
30 #define PLUGIN_AUTHOR "Your name"
31 #define PLUGIN_DATE "January 2010"
32 #define PLUGIN_VERSION "1"
33 #define PLUGIN_DESCRIPTION "Test File Daemon Plugin"
34
35 /* Forward referenced functions */
36 static bRC newPlugin(bpContext *ctx);
37 static bRC freePlugin(bpContext *ctx);
38 static bRC getPluginValue(bpContext *ctx, pVariable var, void *value);
39 static bRC setPluginValue(bpContext *ctx, pVariable var, void *value);
40 static bRC handlePluginEvent(bpContext *ctx, bEvent *event, void *value);
41 static bRC startBackupFile(bpContext *ctx, struct save_pkt *sp);
42 static bRC endBackupFile(bpContext *ctx);
43 static bRC pluginIO(bpContext *ctx, struct io_pkt *io);
44 static bRC startRestoreFile(bpContext *ctx, const char *cmd);
45 static bRC endRestoreFile(bpContext *ctx);
46 static bRC createFile(bpContext *ctx, struct restore_pkt *rp);
47 static bRC setFileAttributes(bpContext *ctx, struct restore_pkt *rp);
48 static bRC checkFile(bpContext *ctx, char *fname);
49 static bRC handleXACLdata(bpContext *ctx, struct xacl_pkt *xacl);
50
51 /* Pointers to Bacula functions */
52 static bFuncs *bfuncs = NULL;
53 static bInfo *binfo = NULL;
54
55 static pInfo pluginInfo = {
56 sizeof(pluginInfo),
57 FD_PLUGIN_INTERFACE_VERSION,
58 FD_PLUGIN_MAGIC,
59 PLUGIN_LICENSE,
60 PLUGIN_AUTHOR,
61 PLUGIN_DATE,
62 PLUGIN_VERSION,
63 PLUGIN_DESCRIPTION,
64 };
65
66 static pFuncs pluginFuncs = {
67 sizeof(pluginFuncs),
68 FD_PLUGIN_INTERFACE_VERSION,
69
70 /* Entry points into plugin */
71 newPlugin, /* new plugin instance */
72 freePlugin, /* free plugin instance */
73 getPluginValue,
74 setPluginValue,
75 handlePluginEvent,
76 startBackupFile,
77 endBackupFile,
78 startRestoreFile,
79 endRestoreFile,
80 pluginIO,
81 createFile,
82 setFileAttributes,
83 checkFile,
84 handleXACLdata
85 };
86
87 /*
88 * Plugin called here when it is first loaded
89 */
90 bRC DLL_IMP_EXP
loadPlugin(bInfo * lbinfo,bFuncs * lbfuncs,pInfo ** pinfo,pFuncs ** pfuncs)91 loadPlugin(bInfo *lbinfo, bFuncs *lbfuncs, pInfo **pinfo, pFuncs **pfuncs)
92 {
93 bfuncs = lbfuncs; /* set Bacula funct pointers */
94 binfo = lbinfo;
95 printf("plugin: Loaded: size=%d version=%d\n", bfuncs->size, bfuncs->version);
96
97 *pinfo = &pluginInfo; /* return pointer to our info */
98 *pfuncs = &pluginFuncs; /* return pointer to our functions */
99
100 return bRC_OK;
101 }
102
103 /*
104 * Plugin called here when it is unloaded, normally when
105 * Bacula is going to exit.
106 */
107 bRC DLL_IMP_EXP
unloadPlugin()108 unloadPlugin()
109 {
110 printf("plugin: Unloaded\n");
111 return bRC_OK;
112 }
113
114 /*
115 * Called here to make a new instance of the plugin -- i.e. when
116 * a new Job is started. There can be multiple instances of
117 * each plugin that are running at the same time. Your
118 * plugin instance must be thread safe and keep its own
119 * local data.
120 */
newPlugin(bpContext * ctx)121 static bRC newPlugin(bpContext *ctx)
122 {
123 int JobId = 0;
124 bfuncs->getBaculaValue(ctx, bVarJobId, (void *)&JobId);
125 // printf("plugin: newPlugin JobId=%d\n", JobId);
126 bfuncs->registerBaculaEvents(ctx, 1, 2, 0);
127 return bRC_OK;
128 }
129
130 /*
131 * Release everything concerning a particular instance of a
132 * plugin. Normally called when the Job terminates.
133 */
freePlugin(bpContext * ctx)134 static bRC freePlugin(bpContext *ctx)
135 {
136 int JobId = 0;
137 bfuncs->getBaculaValue(ctx, bVarJobId, (void *)&JobId);
138 // printf("plugin: freePlugin JobId=%d\n", JobId);
139 return bRC_OK;
140 }
141
142 /*
143 * Called by core code to get a variable from the plugin.
144 * Not currently used.
145 */
getPluginValue(bpContext * ctx,pVariable var,void * value)146 static bRC getPluginValue(bpContext *ctx, pVariable var, void *value)
147 {
148 // printf("plugin: getPluginValue var=%d\n", var);
149 return bRC_OK;
150 }
151
152 /*
153 * Called by core code to set a plugin variable.
154 * Not currently used.
155 */
setPluginValue(bpContext * ctx,pVariable var,void * value)156 static bRC setPluginValue(bpContext *ctx, pVariable var, void *value)
157 {
158 // printf("plugin: setPluginValue var=%d\n", var);
159 return bRC_OK;
160 }
161
162 /*
163 * Called by Bacula when there are certain events that the
164 * plugin might want to know. The value depends on the
165 * event.
166 */
handlePluginEvent(bpContext * ctx,bEvent * event,void * value)167 static bRC handlePluginEvent(bpContext *ctx, bEvent *event, void *value)
168 {
169 char *name;
170
171 switch (event->eventType) {
172 case bEventJobStart:
173 printf("plugin: JobStart=%s\n", NPRT((char *)value));
174 break;
175 case bEventJobEnd:
176 printf("plugin: JobEnd\n");
177 break;
178 case bEventStartBackupJob:
179 printf("plugin: BackupStart\n");
180 break;
181 case bEventEndBackupJob:
182 printf("plugin: BackupEnd\n");
183 break;
184 case bEventLevel:
185 printf("plugin: JobLevel=%c %d\n", (int64_t)value, (int64_t)value);
186 break;
187 case bEventSince:
188 printf("plugin: since=%d\n", (int64_t)value);
189 break;
190 case bEventStartRestoreJob:
191 printf("plugin: StartRestoreJob\n");
192 break;
193 case bEventEndRestoreJob:
194 printf("plugin: EndRestoreJob\n");
195 break;
196 /* Plugin command e.g. plugin = <plugin-name>:<name-space>:command */
197 case bEventRestoreCommand:
198 printf("plugin: backup command=%s\n", NPRT((char *)value));
199 break;
200 case bEventBackupCommand:
201 printf("plugin: backup command=%s\n", NPRT((char *)value));
202 break;
203
204 case bEventComponentInfo:
205 printf("plugin: Component=%s\n", NPRT((char *)value));
206 break;
207
208 default:
209 printf("plugin: unknown event=%d\n", event->eventType);
210 }
211 bfuncs->getBaculaValue(ctx, bVarFDName, (void *)&name);
212 // printf("FD Name=%s\n", name);
213 // bfuncs->JobMessage(ctx, __FILE__, __LINE__, 1, 0, "JobMesssage message");
214 // bfuncs->DebugMessage(ctx, __FILE__, __LINE__, 1, "DebugMesssage message");
215 return bRC_OK;
216 }
217
218 /*
219 * Called when starting to backup a file. Here the plugin must
220 * return the "stat" packet for the directory/file and provide
221 * certain information so that Bacula knows what the file is.
222 * The plugin can create "Virtual" files by giving them a
223 * name that is not normally found on the file system.
224 */
startBackupFile(bpContext * ctx,struct save_pkt * sp)225 static bRC startBackupFile(bpContext *ctx, struct save_pkt *sp)
226 {
227 return bRC_OK;
228 }
229
230 /*
231 * Done backing up a file.
232 */
endBackupFile(bpContext * ctx)233 static bRC endBackupFile(bpContext *ctx)
234 {
235 return bRC_OK;
236 }
237
238 /*
239 * Do actual I/O. Bacula calls this after startBackupFile
240 * or after startRestoreFile to do the actual file
241 * input or output.
242 */
pluginIO(bpContext * ctx,struct io_pkt * io)243 static bRC pluginIO(bpContext *ctx, struct io_pkt *io)
244 {
245 io->status = 0;
246 io->io_errno = 0;
247 switch(io->func) {
248 case IO_OPEN:
249 printf("plugin: IO_OPEN\n");
250 break;
251 case IO_READ:
252 printf("plugin: IO_READ buf=%p len=%d\n", io->buf, io->count);
253 break;
254 case IO_WRITE:
255 printf("plugin: IO_WRITE buf=%p len=%d\n", io->buf, io->count);
256 break;
257 case IO_CLOSE:
258 printf("plugin: IO_CLOSE\n");
259 break;
260 }
261 return bRC_OK;
262 }
263
startRestoreFile(bpContext * ctx,const char * cmd)264 static bRC startRestoreFile(bpContext *ctx, const char *cmd)
265 {
266 return bRC_OK;
267 }
268
endRestoreFile(bpContext * ctx)269 static bRC endRestoreFile(bpContext *ctx)
270 {
271 return bRC_OK;
272 }
273
274 /*
275 * Called here to give the plugin the information needed to
276 * re-create the file on a restore. It basically gets the
277 * stat packet that was created during the backup phase.
278 * This data is what is needed to create the file, but does
279 * not contain actual file data.
280 */
createFile(bpContext * ctx,struct restore_pkt * rp)281 static bRC createFile(bpContext *ctx, struct restore_pkt *rp)
282 {
283 return bRC_OK;
284 }
285
286 /*
287 * Called after the file has been restored. This can be used to
288 * set directory permissions, ...
289 */
setFileAttributes(bpContext * ctx,struct restore_pkt * rp)290 static bRC setFileAttributes(bpContext *ctx, struct restore_pkt *rp)
291 {
292 return bRC_OK;
293 }
294
295 /* When using Incremental dump, all previous dumps are necessary */
checkFile(bpContext * ctx,char * fname)296 static bRC checkFile(bpContext *ctx, char *fname)
297 {
298 return bRC_OK;
299 }
300
301 /*
302 * New Bacula Plugin API require this
303 */
handleXACLdata(bpContext * ctx,struct xacl_pkt * xacl)304 static bRC handleXACLdata(bpContext *ctx, struct xacl_pkt *xacl)
305 {
306 return bRC_OK;
307 }
308
309 #ifdef __cplusplus
310 }
311 #endif
312