]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/plugins/fd/test-plugin-fd.c
Update ACL/XATTR code and define new ACL/XATTR API for Plugins.
[bacula/bacula] / bacula / src / plugins / fd / test-plugin-fd.c
1 /*
2    Bacula(R) - The Network Backup Solution
3
4    Copyright (C) 2000-2015 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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
671 static bRC createFile(bpContext *ctx, struct restore_pkt *rp)
672 {
673    printf("test-plugin-fd: createFile\n");
674    if (strlen(rp->where) > 990) {
675       printf("Restore target dir too long. Restricting to first 990 bytes.\n");
676    }
677    strncpy(((struct plugin_ctx *)ctx->pContext)->where, rp->where, 991);
678    ((struct plugin_ctx *)ctx->pContext)->replace = rp->replace;
679    rp->create_status = CF_EXTRACT;
680    return bRC_OK;
681 }
682
683 /*
684  * We will get here if the File is a directory after everything
685  * is written in the directory.
686  */
687 static bRC setFileAttributes(bpContext *ctx, struct restore_pkt *rp)
688 {
689    printf("test-plugin-fd: setFileAttributes\n");
690    return bRC_OK;
691 }
692
693 /* When using Incremental dump, all previous dumps are necessary */
694 static bRC checkFile(bpContext *ctx, char *fname)
695 {
696    return bRC_OK;
697 }
698
699 /*
700  * New Bacula Plugin API require this
701  */
702 static bRC handleXACLdata(bpContext *ctx, struct xacl_pkt *xacl)
703 {
704    return bRC_OK;
705 }
706
707 #ifdef __cplusplus
708 }
709 #endif