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 /*
20  * A simple test plugin for the Bacula File Daemon derived from
21  *   the bpipe plugin, but used for testing new features.
22  *
23  *  Kern Sibbald, October 2007
24  *
25  */
26 #include "bacula.h"
27 #include "fd_plugins.h"
28 #include "lib/ini.h"
29 #include <wchar.h>
30 
31 #undef malloc
32 #undef free
33 #undef strdup
34 
35 #define fi __FILE__
36 #define li __LINE__
37 
38 #ifdef __cplusplus
39 extern "C" {
40 #endif
41 
42 static const int dbglvl = 000;
43 
44 #define PLUGIN_LICENSE      "AGPLv3"
45 #define PLUGIN_AUTHOR       "Kern Sibbald"
46 #define PLUGIN_DATE         "May 2011"
47 #define PLUGIN_VERSION      "3"
48 #define PLUGIN_DESCRIPTION  "Bacula Test File Daemon Plugin"
49 
50 /* Forward referenced functions */
51 static bRC newPlugin(bpContext *ctx);
52 static bRC freePlugin(bpContext *ctx);
53 static bRC getPluginValue(bpContext *ctx, pVariable var, void *value);
54 static bRC setPluginValue(bpContext *ctx, pVariable var, void *value);
55 static bRC handlePluginEvent(bpContext *ctx, bEvent *event, void *value);
56 static bRC startBackupFile(bpContext *ctx, struct save_pkt *sp);
57 static bRC endBackupFile(bpContext *ctx);
58 static bRC pluginIO(bpContext *ctx, struct io_pkt *io);
59 static bRC startRestoreFile(bpContext *ctx, const char *cmd);
60 static bRC endRestoreFile(bpContext *ctx);
61 static bRC createFile(bpContext *ctx, struct restore_pkt *rp);
62 static bRC setFileAttributes(bpContext *ctx, struct restore_pkt *rp);
63 static bRC checkFile(bpContext *ctx, char *fname);
64 static bRC handleXACLdata(bpContext *ctx, struct xacl_pkt *xacl);
65 
66 /* Pointers to Bacula functions */
67 static bFuncs *bfuncs = NULL;
68 static bInfo  *binfo = NULL;
69 
70 /* Plugin Information block */
71 static pInfo pluginInfo = {
72    sizeof(pluginInfo),
73    FD_PLUGIN_INTERFACE_VERSION,
74    FD_PLUGIN_MAGIC,
75    PLUGIN_LICENSE,
76    PLUGIN_AUTHOR,
77    PLUGIN_DATE,
78    PLUGIN_VERSION,
79    PLUGIN_DESCRIPTION
80 };
81 
82 /* Plugin entry points for Bacula */
83 static pFuncs pluginFuncs = {
84    sizeof(pluginFuncs),
85    FD_PLUGIN_INTERFACE_VERSION,
86 
87    /* Entry points into plugin */
88    newPlugin,                         /* new plugin instance */
89    freePlugin,                        /* free plugin instance */
90    getPluginValue,
91    setPluginValue,
92    handlePluginEvent,
93    startBackupFile,
94    endBackupFile,
95    startRestoreFile,
96    endRestoreFile,
97    pluginIO,
98    createFile,
99    setFileAttributes,
100    checkFile,
101    handleXACLdata
102 };
103 
104 static struct ini_items test_items[] = {
105    // name       handler         comment            required
106    { "string1",  ini_store_str,  "Special String",    1},
107    { "string2",  ini_store_str,  "2nd String",        0},
108    { "ok",       ini_store_bool, "boolean",           0},
109 
110 // We can also use the ITEMS_DEFAULT
111 // { "ok",       ini_store_bool, "boolean",           0, ITEMS_DEFAULT},
112    { NULL,       NULL,           NULL,                0}
113 };
114 
115 /*
116  * Plugin private context
117  */
118 struct plugin_ctx {
119    boffset_t offset;
120    FILE *fd;                          /* pipe file descriptor */
121    char *cmd;                         /* plugin command line */
122    char *fname;                       /* filename to "backup/restore" */
123    char *reader;                      /* reader program for backup */
124    char *writer;                      /* writer program for backup */
125 
126    char where[1000];
127    int replace;
128 
129    int nb_obj;                        /* Number of objects created */
130    POOLMEM *buf;                      /* store ConfigFile */
131 };
132 
133 /*
134  * loadPlugin() and unloadPlugin() are entry points that are
135  *  exported, so Bacula can directly call these two entry points
136  *  they are common to all Bacula plugins.
137  */
138 /*
139  * External entry point called by Bacula to "load the plugin
140  */
loadPlugin(bInfo * lbinfo,bFuncs * lbfuncs,pInfo ** pinfo,pFuncs ** pfuncs)141 bRC loadPlugin(bInfo *lbinfo, bFuncs *lbfuncs, pInfo **pinfo, pFuncs **pfuncs)
142 {
143    bfuncs = lbfuncs;                  /* set Bacula funct pointers */
144    binfo  = lbinfo;
145    *pinfo  = &pluginInfo;             /* return pointer to our info */
146    *pfuncs = &pluginFuncs;            /* return pointer to our functions */
147 
148    return bRC_OK;
149 }
150 
151 /*
152  * External entry point to unload the plugin
153  */
unloadPlugin()154 bRC unloadPlugin()
155 {
156 // printf("test-plugin-fd: Unloaded\n");
157    return bRC_OK;
158 }
159 
160 /*
161  * The following entry points are accessed through the function
162  *   pointers we supplied to Bacula. Each plugin type (dir, fd, sd)
163  *   has its own set of entry points that the plugin must define.
164  */
165 /*
166  * Create a new instance of the plugin i.e. allocate our private storage
167  */
newPlugin(bpContext * ctx)168 static bRC newPlugin(bpContext *ctx)
169 {
170    struct plugin_ctx *p_ctx = (struct plugin_ctx *)malloc(sizeof(struct plugin_ctx));
171    if (!p_ctx) {
172       return bRC_Error;
173    }
174    memset(p_ctx, 0, sizeof(struct plugin_ctx));
175    ctx->pContext = (void *)p_ctx;        /* set our context pointer */
176    return bRC_OK;
177 }
178 
179 /*
180  * Free a plugin instance, i.e. release our private storage
181  */
freePlugin(bpContext * ctx)182 static bRC freePlugin(bpContext *ctx)
183 {
184    struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext;
185    if (!p_ctx) {
186       return bRC_Error;
187    }
188    if (p_ctx->buf) {
189       free_pool_memory(p_ctx->buf);
190    }
191    if (p_ctx->cmd) {
192       free(p_ctx->cmd);                  /* free any allocated command string */
193    }
194    free(p_ctx);                          /* free our private context */
195    ctx->pContext = NULL;
196    return bRC_OK;
197 }
198 
199 /*
200  * Return some plugin value (none defined)
201  */
getPluginValue(bpContext * ctx,pVariable var,void * value)202 static bRC getPluginValue(bpContext *ctx, pVariable var, void *value)
203 {
204    return bRC_OK;
205 }
206 
207 /*
208  * Set a plugin value (none defined)
209  */
setPluginValue(bpContext * ctx,pVariable var,void * value)210 static bRC setPluginValue(bpContext *ctx, pVariable var, void *value)
211 {
212    return bRC_OK;
213 }
214 
215 /*
216  * Handle an event that was generated in Bacula
217  */
handlePluginEvent(bpContext * ctx,bEvent * event,void * value)218 static bRC handlePluginEvent(bpContext *ctx, bEvent *event, void *value)
219 {
220    struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext;
221    restore_object_pkt *rop;
222    if (!p_ctx) {
223       return bRC_Error;
224    }
225 
226 // char *name;
227 
228    /*
229     * Most events don't interest us so we ignore them.
230     *   the printfs are so that plugin writers can enable them to see
231     *   what is really going on.
232     */
233    switch (event->eventType) {
234    case bEventJobStart:
235       bfuncs->DebugMessage(ctx, fi, li, dbglvl, "test-plugin-fd: JobStart=%s\n", (char *)value);
236       break;
237    case bEventJobEnd:
238    case bEventEndBackupJob:
239    case bEventLevel:
240    case bEventSince:
241    case bEventStartRestoreJob:
242    case bEventEndRestoreJob:
243       break;
244    /* End of Dir FileSet commands, now we can add excludes */
245    case bEventEndFileSet:
246       bfuncs->NewOptions(ctx);
247       bfuncs->AddWild(ctx, "*.c", ' ');
248       bfuncs->AddWild(ctx, "*.cpp", ' ');
249       bfuncs->AddOptions(ctx, "ei");         /* exclude, ignore case */
250       bfuncs->AddExclude(ctx, "/home/kern/bacula/regress/README");
251       break;
252    case bEventStartBackupJob:
253       break;
254    case bEventRestoreObject:
255    {
256       printf("Plugin RestoreObject\n");
257       if (!value) {
258          bfuncs->DebugMessage(ctx, fi, li, dbglvl, "test-plugin-fd: End restore objects\n");
259          break;
260       }
261       rop = (restore_object_pkt *)value;
262       bfuncs->DebugMessage(ctx, fi, li, dbglvl,
263                            "Get RestoreObject len=%d JobId=%d oname=%s type=%d data=%.127s\n",
264                            rop->object_len, rop->JobId, rop->object_name, rop->object_type,
265                            rop->object);
266       FILE *fp;
267       POOLMEM *q;
268       char *working;
269       static int _nb=0;
270       q = get_pool_memory(PM_FNAME);
271 
272       bfuncs->getBaculaValue(ctx, bVarWorkingDir, &working);
273       Mmsg(q, "%s/restore.%d", working, _nb++);
274       if ((fp = fopen(q, "w")) != NULL) {
275          fwrite(rop->object, rop->object_len, 1, fp);
276          fclose(fp);
277       }
278 
279       free_pool_memory(q);
280 
281       if (!strcmp(rop->object_name, INI_RESTORE_OBJECT_NAME)) {
282          ConfigFile ini;
283          if (!ini.dump_string(rop->object, rop->object_len)) {
284             break;
285          }
286          ini.register_items(test_items, sizeof(struct ini_items));
287          if (ini.parse(ini.out_fname)) {
288             bfuncs->JobMessage(ctx, fi, li, M_INFO, 0, "string1 = %s\n",
289                                ini.items[0].val.strval);
290          } else {
291             bfuncs->JobMessage(ctx, fi, li, M_ERROR, 0, "Can't parse config\n");
292          }
293       }
294 
295       break;
296    }
297    /* Plugin command e.g. plugin = <plugin-name>:<name-space>:read command:write command */
298    case bEventRestoreCommand:
299       /* Fall-through wanted */
300    case bEventEstimateCommand:
301       /* Fall-through wanted */
302    case bEventBackupCommand:
303    {
304       char *p;
305       bfuncs->DebugMessage(ctx, fi, li, dbglvl, "test-plugin-fd: pluginEvent cmd=%s\n", (char *)value);
306       p_ctx->cmd = strdup((char *)value);
307       p = strchr(p_ctx->cmd, ':');
308       if (!p) {
309          bfuncs->JobMessage(ctx, fi, li, M_FATAL, 0, "Plugin terminator not found: %s\n", (char *)value);
310          return bRC_Error;
311       }
312       *p++ = 0;           /* terminate plugin */
313       p_ctx->fname = p;
314       p = strchr(p, ':');
315       if (!p) {
316          bfuncs->JobMessage(ctx, fi, li, M_FATAL, 0, "File terminator not found: %s\n", (char *)value);
317          return bRC_Error;
318       }
319       *p++ = 0;           /* terminate file */
320       p_ctx->reader = p;
321       p = strchr(p, ':');
322       if (!p) {
323          bfuncs->JobMessage(ctx, fi, li, M_FATAL, 0, "Reader terminator not found: %s\n", (char *)value);
324          return bRC_Error;
325       }
326       *p++ = 0;           /* terminate reader string */
327       p_ctx->writer = p;
328       printf("test-plugin-fd: plugin=%s fname=%s reader=%s writer=%s\n",
329           p_ctx->cmd, p_ctx->fname, p_ctx->reader, p_ctx->writer);
330       break;
331    }
332    case bEventPluginCommand:
333       break;
334    case bEventVssBeforeCloseRestore:
335       break;
336    case bEventComponentInfo:
337       printf("plugin: Component=%s\n", NPRT((char *)value));
338       break;
339 
340    default:
341       printf("test-plugin-fd: unknown event=%d\n", event->eventType);
342       break;
343    }
344    return bRC_OK;
345 }
346 
347 /*
348  * Start the backup of a specific file
349  */
startBackupFile(bpContext * ctx,struct save_pkt * sp)350 static bRC startBackupFile(bpContext *ctx, struct save_pkt *sp)
351 {
352    struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext;
353    if (!p_ctx) {
354       return bRC_Error;
355    }
356 
357    if (p_ctx->nb_obj == 0) {
358       sp->fname = (char *)"takeme.h";
359       bfuncs->DebugMessage(ctx, fi, li, dbglvl, "AcceptFile=%s = %d\n",
360                            sp->fname, bfuncs->AcceptFile(ctx, sp));
361 
362       sp->fname = (char *)"/path/to/excludeme.o";
363       bfuncs->DebugMessage(ctx, fi, li, dbglvl, "AcceptFile=%s = %d\n",
364                            sp->fname, bfuncs->AcceptFile(ctx, sp));
365 
366       sp->fname = (char *)"/path/to/excludeme.c";
367       bfuncs->DebugMessage(ctx, fi, li, dbglvl, "AcceptFile=%s = %d\n",
368                            sp->fname, bfuncs->AcceptFile(ctx, sp));
369    }
370 
371    if (p_ctx->nb_obj == 0) {
372       sp->object_name = (char *)"james.xml";
373       sp->object = (char *)"This is test data for the restore object. "
374   "garbage=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
375   "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
376   "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
377   "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
378   "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
379   "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
380   "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
381   "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
382   "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
383   "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
384   "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
385   "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
386   "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
387   "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
388   "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
389   "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
390   "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
391   "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
392   "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
393   "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
394   "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
395   "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
396   "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
397   "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
398   "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
399   "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
400   "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
401   "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
402   "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
403   "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
404   "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
405   "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
406   "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
407   "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
408   "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
409   "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
410   "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
411   "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
412   "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
413   "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
414   "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
415   "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
416   "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
417   "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
418   "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
419   "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
420   "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
421   "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
422   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
423   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
424   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
425   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
426   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
427   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
428   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
429   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
430   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
431   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
432   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
433   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
434   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
435   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
436   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
437   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
438   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
439   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
440   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
441   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
442   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
443   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
444   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
445   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
446   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
447   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
448   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
449   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
450   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
451   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
452   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
453   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
454   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
455   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
456   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
457   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
458   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
459   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
460   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
461   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
462   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
463   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
464   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
465   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
466   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
467   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
468   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
469   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
470   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
471   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
472   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
473   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
474   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
475   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
476   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
477   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
478   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
479   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
480   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
481   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
482   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
483   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
484   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
485   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
486   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
487   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
488   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
489   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
490   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
491   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
492   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
493   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
494   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
495   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
496   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
497   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
498   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
499   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
500   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
501   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
502   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
503   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
504   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
505   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
506   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
507   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
508   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
509   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
510   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
511   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
512   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
513   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
514   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
515   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
516   "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
517   "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
518   "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
519   "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
520   "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
521   "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
522   "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
523   "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
524   "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
525   "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
526   "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
527   "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
528   "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
529   "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
530   "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
531   "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
532   "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
533   "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
534   "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
535   "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
536   "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
537   "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
538   "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
539   "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
540   "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
541   "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
542   "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
543   "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
544   "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
545   "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
546   "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
547   "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
548   "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
549   "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
550   "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
551   "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
552   "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
553   "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
554   "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
555   "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
556   "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
557   "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
558   "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
559   "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
560   "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
561   "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
562   "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
563   "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
564   "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
565   "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
566   "\0secret";
567       sp->object_len = strlen(sp->object)+1+6+1; /* str + 0 + secret + 0 */
568       sp->type = FT_RESTORE_FIRST;
569 
570       static int _nb=0;
571       POOLMEM *q = get_pool_memory(PM_FNAME);
572       char *working;
573       FILE *fp;
574 
575       bfuncs->getBaculaValue(ctx, bVarWorkingDir, &working);
576       Mmsg(q, "%s/torestore.%d", working, _nb++);
577       if ((fp = fopen(q, "w")) != NULL) {
578          fwrite(sp->object, sp->object_len, 1, fp);
579          fclose(fp);
580       }
581       free_pool_memory(q);
582 
583    } else if (p_ctx->nb_obj == 1) {
584       ConfigFile ini;
585       p_ctx->buf = get_pool_memory(PM_BSOCK);
586       ini.register_items(test_items, sizeof(struct ini_items));
587 
588       sp->object_name = (char*)INI_RESTORE_OBJECT_NAME;
589       sp->object_len = ini.serialize(&p_ctx->buf);
590       sp->object = p_ctx->buf;
591       sp->type = FT_PLUGIN_CONFIG;
592 
593       Dmsg1(0, "RestoreOptions=<%s>\n", p_ctx->buf);
594    }
595 
596    time_t now = time(NULL);
597    sp->index = ++p_ctx->nb_obj;
598    sp->statp.st_mode = 0700 | S_IFREG;
599    sp->statp.st_ctime = now;
600    sp->statp.st_mtime = now;
601    sp->statp.st_atime = now;
602    sp->statp.st_size = sp->object_len;
603    sp->statp.st_blksize = 4096;
604    sp->statp.st_blocks = 1;
605    bfuncs->DebugMessage(ctx, fi, li, dbglvl,
606                         "Creating RestoreObject len=%d oname=%s data=%.127s\n",
607                         sp->object_len, sp->object_name, sp->object);
608 
609    printf("test-plugin-fd: startBackupFile\n");
610    return bRC_OK;
611 }
612 
613 /*
614  * Done with backup of this file
615  */
endBackupFile(bpContext * ctx)616 static bRC endBackupFile(bpContext *ctx)
617 {
618    /*
619     * We would return bRC_More if we wanted startBackupFile to be
620     * called again to backup another file
621     */
622    return bRC_OK;
623 }
624 
625 
626 /*
627  * Bacula is calling us to do the actual I/O
628  */
pluginIO(bpContext * ctx,struct io_pkt * io)629 static bRC pluginIO(bpContext *ctx, struct io_pkt *io)
630 {
631    struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext;
632    if (!p_ctx) {
633       return bRC_Error;
634    }
635 
636    io->status = 0;
637    io->io_errno = 0;
638    return bRC_OK;
639 }
640 
641 /*
642  * Bacula is notifying us that a plugin name string was found, and
643  *   passing us the plugin command, so we can prepare for a restore.
644  */
startRestoreFile(bpContext * ctx,const char * cmd)645 static bRC startRestoreFile(bpContext *ctx, const char *cmd)
646 {
647    printf("test-plugin-fd: startRestoreFile cmd=%s\n", cmd);
648    return bRC_OK;
649 }
650 
651 /*
652  * Bacula is notifying us that the plugin data has terminated, so
653  *  the restore for this particular file is done.
654  */
endRestoreFile(bpContext * ctx)655 static bRC endRestoreFile(bpContext *ctx)
656 {
657    printf("test-plugin-fd: endRestoreFile\n");
658    return bRC_OK;
659 }
660 
661 /*
662  * This is called during restore to create the file (if necessary)
663  * We must return in rp->create_status:
664  *
665  *  CF_ERROR    -- error
666  *  CF_SKIP     -- skip processing this file
667  *  CF_EXTRACT  -- extract the file (i.e.call i/o routines)
668  *  CF_CREATED  -- created, but no content to extract (typically directories)
669  *
670  */
createFile(bpContext * ctx,struct restore_pkt * rp)671 static bRC createFile(bpContext *ctx, struct restore_pkt *rp)
672 {
673    struct plugin_ctx *pctx = (struct plugin_ctx *)ctx->pContext;
674    printf("test-plugin-fd: createFile\n");
675    if (strlen(rp->where) > 990) {
676       printf("Restore target dir too long. Restricting to first 990 bytes.\n");
677    }
678    bstrncpy(pctx->where, rp->where, sizeof(pctx->where));
679    pctx->replace = rp->replace;
680    rp->create_status = CF_CORE;
681    return bRC_OK;
682 }
683 
684 /*
685  * We will get here if the File is a directory after everything
686  * is written in the directory.
687  */
setFileAttributes(bpContext * ctx,struct restore_pkt * rp)688 static bRC setFileAttributes(bpContext *ctx, struct restore_pkt *rp)
689 {
690    printf("test-plugin-fd: setFileAttributes\n");
691    return bRC_OK;
692 }
693 
694 /* When using Incremental dump, all previous dumps are necessary */
checkFile(bpContext * ctx,char * fname)695 static bRC checkFile(bpContext *ctx, char *fname)
696 {
697    return bRC_OK;
698 }
699 
700 /*
701  * New Bacula Plugin API require this
702  */
handleXACLdata(bpContext * ctx,struct xacl_pkt * xacl)703 static bRC handleXACLdata(bpContext *ctx, struct xacl_pkt *xacl)
704 {
705    return bRC_OK;
706 }
707 
708 #ifdef __cplusplus
709 }
710 #endif
711